mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 14:35:56 +08:00
commit
4bbe1ea614
1
.github/workflows/build.yaml
vendored
1
.github/workflows/build.yaml
vendored
@ -36,6 +36,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo 'INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > frontend/.env
|
echo 'INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > frontend/.env
|
||||||
echo 'SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env
|
echo 'SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env
|
||||||
|
echo 'CLARITY_PROJECT_ID="${{ secrets.CLARITY_PROJECT_ID }}"' >> frontend/.env
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: cd frontend && yarn install
|
run: cd frontend && yarn install
|
||||||
- name: Run ESLint
|
- name: Run ESLint
|
||||||
|
1
.github/workflows/push.yaml
vendored
1
.github/workflows/push.yaml
vendored
@ -133,6 +133,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo 'INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > frontend/.env
|
echo 'INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > frontend/.env
|
||||||
echo 'SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env
|
echo 'SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env
|
||||||
|
echo 'CLARITY_PROJECT_ID="${{ secrets.CLARITY_PROJECT_ID }}"' >> frontend/.env
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
working-directory: frontend
|
working-directory: frontend
|
||||||
run: yarn install
|
run: yarn install
|
||||||
|
3
Makefile
3
Makefile
@ -151,4 +151,5 @@ test:
|
|||||||
go test ./pkg/query-service/app/querier/...
|
go test ./pkg/query-service/app/querier/...
|
||||||
go test ./pkg/query-service/converter/...
|
go test ./pkg/query-service/converter/...
|
||||||
go test ./pkg/query-service/formatter/...
|
go test ./pkg/query-service/formatter/...
|
||||||
go test ./pkg/query-service/tests/integration/...
|
go test ./pkg/query-service/tests/integration/...
|
||||||
|
go test ./pkg/query-service/rules/...
|
||||||
|
@ -144,7 +144,7 @@ services:
|
|||||||
condition: on-failure
|
condition: on-failure
|
||||||
|
|
||||||
query-service:
|
query-service:
|
||||||
image: signoz/query-service:0.29.3
|
image: signoz/query-service:0.30.0
|
||||||
command:
|
command:
|
||||||
[
|
[
|
||||||
"-config=/root/config/prometheus.yml",
|
"-config=/root/config/prometheus.yml",
|
||||||
@ -184,7 +184,7 @@ services:
|
|||||||
<<: *clickhouse-depend
|
<<: *clickhouse-depend
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
image: signoz/frontend:0.29.3
|
image: signoz/frontend:0.30.0
|
||||||
deploy:
|
deploy:
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: on-failure
|
||||||
|
@ -162,7 +162,7 @@ services:
|
|||||||
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
|
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
|
||||||
|
|
||||||
query-service:
|
query-service:
|
||||||
image: signoz/query-service:${DOCKER_TAG:-0.29.3}
|
image: signoz/query-service:${DOCKER_TAG:-0.30.0}
|
||||||
container_name: signoz-query-service
|
container_name: signoz-query-service
|
||||||
command:
|
command:
|
||||||
[
|
[
|
||||||
@ -201,7 +201,7 @@ services:
|
|||||||
<<: *clickhouse-depend
|
<<: *clickhouse-depend
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
image: signoz/frontend:${DOCKER_TAG:-0.29.3}
|
image: signoz/frontend:${DOCKER_TAG:-0.30.0}
|
||||||
container_name: signoz-frontend
|
container_name: signoz-frontend
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
depends_on:
|
depends_on:
|
||||||
|
6
frontend/.prettierignore
Normal file
6
frontend/.prettierignore
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Ignore artifacts:
|
||||||
|
build
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# Ignore all MD files:
|
||||||
|
**/*.md
|
@ -7,7 +7,7 @@ const config: Config.InitialOptions = {
|
|||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
|
||||||
modulePathIgnorePatterns: ['dist'],
|
modulePathIgnorePatterns: ['dist'],
|
||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
'\\.(css|less)$': '<rootDir>/__mocks__/cssMock.ts',
|
'\\.(css|less|scss)$': '<rootDir>/__mocks__/cssMock.ts',
|
||||||
},
|
},
|
||||||
globals: {
|
globals: {
|
||||||
extensionsToTreatAsEsm: ['.ts'],
|
extensionsToTreatAsEsm: ['.ts'],
|
||||||
|
@ -84,9 +84,11 @@
|
|||||||
"react-helmet-async": "1.3.0",
|
"react-helmet-async": "1.3.0",
|
||||||
"react-i18next": "^11.16.1",
|
"react-i18next": "^11.16.1",
|
||||||
"react-intersection-observer": "9.4.1",
|
"react-intersection-observer": "9.4.1",
|
||||||
|
"react-markdown": "8.0.7",
|
||||||
"react-query": "^3.34.19",
|
"react-query": "^3.34.19",
|
||||||
"react-redux": "^7.2.2",
|
"react-redux": "^7.2.2",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
|
"react-syntax-highlighter": "15.5.0",
|
||||||
"react-use": "^17.3.2",
|
"react-use": "^17.3.2",
|
||||||
"react-virtuoso": "4.0.3",
|
"react-virtuoso": "4.0.3",
|
||||||
"redux": "^4.0.5",
|
"redux": "^4.0.5",
|
||||||
@ -150,6 +152,7 @@
|
|||||||
"@types/react-redux": "^7.1.11",
|
"@types/react-redux": "^7.1.11",
|
||||||
"@types/react-resizable": "3.0.3",
|
"@types/react-resizable": "3.0.3",
|
||||||
"@types/react-router-dom": "^5.1.6",
|
"@types/react-router-dom": "^5.1.6",
|
||||||
|
"@types/react-syntax-highlighter": "15.5.7",
|
||||||
"@types/styled-components": "^5.1.4",
|
"@types/styled-components": "^5.1.4",
|
||||||
"@types/uuid": "^8.3.1",
|
"@types/uuid": "^8.3.1",
|
||||||
"@types/webpack": "^5.28.0",
|
"@types/webpack": "^5.28.0",
|
||||||
@ -183,6 +186,7 @@
|
|||||||
"lint-staged": "^12.5.0",
|
"lint-staged": "^12.5.0",
|
||||||
"portfinder-sync": "^0.0.2",
|
"portfinder-sync": "^0.0.2",
|
||||||
"prettier": "2.2.1",
|
"prettier": "2.2.1",
|
||||||
|
"raw-loader": "4.0.2",
|
||||||
"react-hooks-testing-library": "0.6.0",
|
"react-hooks-testing-library": "0.6.0",
|
||||||
"react-hot-loader": "^4.13.0",
|
"react-hot-loader": "^4.13.0",
|
||||||
"react-resizable": "3.0.4",
|
"react-resizable": "3.0.4",
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
"delete_processor_description": "Logs are processed sequentially in processors. Deleting a processor may change content of data processed by other processors",
|
"delete_processor_description": "Logs are processed sequentially in processors. Deleting a processor may change content of data processed by other processors",
|
||||||
"search_pipeline_placeholder": "Filter Pipelines",
|
"search_pipeline_placeholder": "Filter Pipelines",
|
||||||
"pipeline_name_placeholder": "Name",
|
"pipeline_name_placeholder": "Name",
|
||||||
|
"pipeline_filter_placeholder": "Filter for selecting logs to be processed by this pipeline. Example: service_name = billing",
|
||||||
"pipeline_tags_placeholder": "Tags",
|
"pipeline_tags_placeholder": "Tags",
|
||||||
"pipeline_description_placeholder": "Enter description for your pipeline",
|
"pipeline_description_placeholder": "Enter description for your pipeline",
|
||||||
"processor_name_placeholder": "Name",
|
"processor_name_placeholder": "Name",
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import { ConfigProvider } from 'antd';
|
import { ConfigProvider } from 'antd';
|
||||||
|
import getLocalStorageApi from 'api/browser/localstorage/get';
|
||||||
|
import setLocalStorageApi from 'api/browser/localstorage/set';
|
||||||
import NotFound from 'components/NotFound';
|
import NotFound from 'components/NotFound';
|
||||||
import Spinner from 'components/Spinner';
|
import Spinner from 'components/Spinner';
|
||||||
import { FeatureKeys } from 'constants/features';
|
import { FeatureKeys } from 'constants/features';
|
||||||
|
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import AppLayout from 'container/AppLayout';
|
import AppLayout from 'container/AppLayout';
|
||||||
import { useThemeConfig } from 'hooks/useDarkMode';
|
import { useThemeConfig } from 'hooks/useDarkMode';
|
||||||
@ -75,14 +78,26 @@ function App(): JSX.Element {
|
|||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isLoggedInState && user && user.userId && user.email) {
|
const isIdentifiedUser = getLocalStorageApi(LOCALSTORAGE.IS_IDENTIFIED_USER);
|
||||||
|
|
||||||
|
if (
|
||||||
|
isLoggedInState &&
|
||||||
|
user &&
|
||||||
|
user.userId &&
|
||||||
|
user.email &&
|
||||||
|
!isIdentifiedUser
|
||||||
|
) {
|
||||||
|
setLocalStorageApi(LOCALSTORAGE.IS_IDENTIFIED_USER, 'true');
|
||||||
|
|
||||||
window.analytics.identify(user?.email, {
|
window.analytics.identify(user?.email, {
|
||||||
email: user?.email,
|
email: user?.email,
|
||||||
name: user?.name,
|
name: user?.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.clarity('identify', user.email, user.name);
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [isLoggedInState]);
|
}, [isLoggedInState, user]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
trackPageView(pathname);
|
trackPageView(pathname);
|
||||||
|
@ -14,7 +14,11 @@ import {
|
|||||||
export const Logout = (): void => {
|
export const Logout = (): void => {
|
||||||
deleteLocalStorageKey(LOCALSTORAGE.AUTH_TOKEN);
|
deleteLocalStorageKey(LOCALSTORAGE.AUTH_TOKEN);
|
||||||
deleteLocalStorageKey(LOCALSTORAGE.IS_LOGGED_IN);
|
deleteLocalStorageKey(LOCALSTORAGE.IS_LOGGED_IN);
|
||||||
|
deleteLocalStorageKey(LOCALSTORAGE.IS_IDENTIFIED_USER);
|
||||||
deleteLocalStorageKey(LOCALSTORAGE.REFRESH_AUTH_TOKEN);
|
deleteLocalStorageKey(LOCALSTORAGE.REFRESH_AUTH_TOKEN);
|
||||||
|
deleteLocalStorageKey(LOCALSTORAGE.LOGGED_IN_USER_EMAIL);
|
||||||
|
deleteLocalStorageKey(LOCALSTORAGE.LOGGED_IN_USER_NAME);
|
||||||
|
deleteLocalStorageKey(LOCALSTORAGE.CHAT_SUPPORT);
|
||||||
|
|
||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: LOGGED_IN,
|
type: LOGGED_IN,
|
||||||
|
@ -30,6 +30,7 @@ import { useNotifications } from 'hooks/useNotifications';
|
|||||||
import { mapCompositeQueryFromQuery } from 'lib/newQueryBuilder/queryBuilderMappers/mapCompositeQueryFromQuery';
|
import { mapCompositeQueryFromQuery } from 'lib/newQueryBuilder/queryBuilderMappers/mapCompositeQueryFromQuery';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useCopyToClipboard } from 'react-use';
|
import { useCopyToClipboard } from 'react-use';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import { ExploreHeaderToolTip, SaveButtonText } from './constants';
|
import { ExploreHeaderToolTip, SaveButtonText } from './constants';
|
||||||
import MenuItemGenerator from './MenuItemGenerator';
|
import MenuItemGenerator from './MenuItemGenerator';
|
||||||
@ -170,6 +171,7 @@ function ExplorerCard({
|
|||||||
{viewsData?.data.data && viewsData?.data.data.length && (
|
{viewsData?.data.data && viewsData?.data.data.length && (
|
||||||
<Space>
|
<Space>
|
||||||
<Select
|
<Select
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
loading={isLoading || isRefetching}
|
loading={isLoading || isRefetching}
|
||||||
showSearch
|
showSearch
|
||||||
placeholder="Select a view"
|
placeholder="Select a view"
|
||||||
@ -204,6 +206,7 @@ function ExplorerCard({
|
|||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<Popover
|
<Popover
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
placement="bottomLeft"
|
placement="bottomLeft"
|
||||||
trigger="click"
|
trigger="click"
|
||||||
content={
|
content={
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { DeleteOutlined } from '@ant-design/icons';
|
import { DeleteOutlined } from '@ant-design/icons';
|
||||||
import { Col, Row, Typography } from 'antd';
|
import { Col, Row, Tooltip, Typography } from 'antd';
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
import { useDeleteView } from 'hooks/saveViews/useDeleteView';
|
import { useDeleteView } from 'hooks/saveViews/useDeleteView';
|
||||||
import { useHandleExplorerTabChange } from 'hooks/useHandleExplorerTabChange';
|
import { useHandleExplorerTabChange } from 'hooks/useHandleExplorerTabChange';
|
||||||
@ -8,7 +8,11 @@ import { MouseEvent, useCallback } from 'react';
|
|||||||
|
|
||||||
import { MenuItemContainer } from './styles';
|
import { MenuItemContainer } from './styles';
|
||||||
import { MenuItemLabelGeneratorProps } from './types';
|
import { MenuItemLabelGeneratorProps } from './types';
|
||||||
import { deleteViewHandler, getViewDetailsUsingViewKey } from './utils';
|
import {
|
||||||
|
deleteViewHandler,
|
||||||
|
getViewDetailsUsingViewKey,
|
||||||
|
trimViewName,
|
||||||
|
} from './utils';
|
||||||
|
|
||||||
function MenuItemGenerator({
|
function MenuItemGenerator({
|
||||||
viewName,
|
viewName,
|
||||||
@ -71,12 +75,16 @@ function MenuItemGenerator({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const newViewName = trimViewName(viewName);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuItemContainer onClick={onLabelClickHandler}>
|
<MenuItemContainer onClick={onLabelClickHandler}>
|
||||||
<Row justify="space-between">
|
<Row justify="space-between">
|
||||||
<Col span={22}>
|
<Col span={22}>
|
||||||
<Row>
|
<Row>
|
||||||
<Typography.Text strong>{viewName}</Typography.Text>
|
<Tooltip title={viewName}>
|
||||||
|
<Typography.Text strong>{newViewName}</Typography.Text>
|
||||||
|
</Tooltip>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Typography.Text type="secondary">Created by {createdBy}</Typography.Text>
|
<Typography.Text type="secondary">Created by {createdBy}</Typography.Text>
|
||||||
|
@ -174,3 +174,10 @@ export const deleteViewHandler = ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const trimViewName = (viewName: string): string => {
|
||||||
|
if (viewName.length > 20) {
|
||||||
|
return `${viewName.substring(0, 20)}...`;
|
||||||
|
}
|
||||||
|
return viewName;
|
||||||
|
};
|
||||||
|
@ -60,12 +60,14 @@ function RawLogView({
|
|||||||
const isDarkMode = useIsDarkMode();
|
const isDarkMode = useIsDarkMode();
|
||||||
const isReadOnlyLog = !isLogsExplorerPage || isReadOnly;
|
const isReadOnlyLog = !isLogsExplorerPage || isReadOnly;
|
||||||
|
|
||||||
|
const severityText = data.severity_text ? `${data.severity_text} |` : '';
|
||||||
|
|
||||||
const text = useMemo(
|
const text = useMemo(
|
||||||
() =>
|
() =>
|
||||||
typeof data.timestamp === 'string'
|
typeof data.timestamp === 'string'
|
||||||
? `${dayjs(data.timestamp).format()} | ${data.body}`
|
? `${dayjs(data.timestamp).format()} | ${severityText} ${data.body}`
|
||||||
: `${dayjs(data.timestamp / 1e6).format()} | ${data.body}`,
|
: `${dayjs(data.timestamp / 1e6).format()} | ${severityText} ${data.body}`,
|
||||||
[data.timestamp, data.body],
|
[data.timestamp, data.body, severityText],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleClickExpand = useCallback(() => {
|
const handleClickExpand = useCallback(() => {
|
||||||
@ -114,11 +116,6 @@ function RawLogView({
|
|||||||
[text],
|
[text],
|
||||||
);
|
);
|
||||||
|
|
||||||
const mouseActions = useMemo(
|
|
||||||
() => ({ onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave }),
|
|
||||||
[handleMouseEnter, handleMouseLeave],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RawLogViewContainer
|
<RawLogViewContainer
|
||||||
onClick={handleClickExpand}
|
onClick={handleClickExpand}
|
||||||
@ -127,8 +124,8 @@ function RawLogView({
|
|||||||
$isDarkMode={isDarkMode}
|
$isDarkMode={isDarkMode}
|
||||||
$isReadOnly={isReadOnly}
|
$isReadOnly={isReadOnly}
|
||||||
$isActiveLog={isHighlighted}
|
$isActiveLog={isHighlighted}
|
||||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
onMouseEnter={handleMouseEnter}
|
||||||
{...mouseActions}
|
onMouseLeave={handleMouseLeave}
|
||||||
>
|
>
|
||||||
{!isReadOnly && (
|
{!isReadOnly && (
|
||||||
<ExpandIconWrapper flex="30px">
|
<ExpandIconWrapper flex="30px">
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
.code-snippet-container {
|
||||||
|
position: relative;
|
||||||
|
background-color: rgb(43, 43, 43);
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-copy-btn {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 8px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
background-color: rgba($color: #1d1d1d, $alpha: 0.7);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: all 0.1s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba($color: #1d1d1d, $alpha: 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.copied {
|
||||||
|
button {
|
||||||
|
background-color: rgba($color: #52c41a, $alpha: 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
import './CodeCopyBtn.scss';
|
||||||
|
|
||||||
|
import { CheckOutlined, CopyOutlined } from '@ant-design/icons';
|
||||||
|
import cx from 'classnames';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
export default function CodeCopyBtn({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}): JSX.Element {
|
||||||
|
const [isSnippetCopied, setIsSnippetCopied] = useState(false);
|
||||||
|
|
||||||
|
const handleClick = (): void => {
|
||||||
|
if (children && Array.isArray(children)) {
|
||||||
|
setIsSnippetCopied(true);
|
||||||
|
navigator.clipboard.writeText(children[0].props.children[0]).finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsSnippetCopied(false);
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cx('code-copy-btn', isSnippetCopied ? 'copied' : '')}>
|
||||||
|
<button type="button" onClick={handleClick}>
|
||||||
|
{!isSnippetCopied ? <CopyOutlined /> : <CheckOutlined />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
/* eslint-disable react/jsx-props-no-spreading */
|
||||||
|
import { CodeProps } from 'react-markdown/lib/ast-to-react';
|
||||||
|
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||||
|
import { a11yDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
|
||||||
|
|
||||||
|
import CodeCopyBtn from './CodeCopyBtn/CodeCopyBtn';
|
||||||
|
|
||||||
|
function Pre({ children }: { children: React.ReactNode }): JSX.Element {
|
||||||
|
return (
|
||||||
|
<pre className="code-snippet-container">
|
||||||
|
<CodeCopyBtn>{children}</CodeCopyBtn>
|
||||||
|
{children}
|
||||||
|
</pre>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Code({
|
||||||
|
node,
|
||||||
|
inline,
|
||||||
|
className = 'blog-code',
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: CodeProps): JSX.Element {
|
||||||
|
const match = /language-(\w+)/.exec(className || '');
|
||||||
|
return !inline && match ? (
|
||||||
|
<SyntaxHighlighter
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
style={a11yDark}
|
||||||
|
language={match[1]}
|
||||||
|
PreTag="div"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{String(children).replace(/\n$/, '')}
|
||||||
|
</SyntaxHighlighter>
|
||||||
|
) : (
|
||||||
|
<code className={className} {...props}>
|
||||||
|
{children}
|
||||||
|
</code>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Code, Pre };
|
@ -7,6 +7,7 @@ import { Tooltip } from 'antd';
|
|||||||
import { themeColors } from 'constants/theme';
|
import { themeColors } from 'constants/theme';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import { style } from './styles';
|
import { style } from './styles';
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ function TextToolTip({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip overlay={overlay}>
|
<Tooltip getTooltipContainer={popupContainer} overlay={overlay}>
|
||||||
{useFilledIcon ? (
|
{useFilledIcon ? (
|
||||||
<QuestionCircleFilled style={iconStyle} />
|
<QuestionCircleFilled style={iconStyle} />
|
||||||
) : (
|
) : (
|
||||||
|
@ -14,4 +14,5 @@ export enum LOCALSTORAGE {
|
|||||||
LOGGED_IN_USER_NAME = 'LOGGED_IN_USER_NAME',
|
LOGGED_IN_USER_NAME = 'LOGGED_IN_USER_NAME',
|
||||||
LOGGED_IN_USER_EMAIL = 'LOGGED_IN_USER_EMAIL',
|
LOGGED_IN_USER_EMAIL = 'LOGGED_IN_USER_EMAIL',
|
||||||
CHAT_SUPPORT = 'CHAT_SUPPORT',
|
CHAT_SUPPORT = 'CHAT_SUPPORT',
|
||||||
|
IS_IDENTIFIED_USER = 'IS_IDENTIFIED_USER',
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ export const mapOfOperators = {
|
|||||||
traces: tracesAggregateOperatorOptions,
|
traces: tracesAggregateOperatorOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mapOfFilters: Record<DataSource, QueryAdditionalFilter[]> = {
|
export const mapOfQueryFilters: Record<DataSource, QueryAdditionalFilter[]> = {
|
||||||
metrics: [
|
metrics: [
|
||||||
// eslint-disable-next-line sonarjs/no-duplicate-string
|
// eslint-disable-next-line sonarjs/no-duplicate-string
|
||||||
{ text: 'Aggregation interval', field: 'stepInterval' },
|
{ text: 'Aggregation interval', field: 'stepInterval' },
|
||||||
@ -94,6 +94,24 @@ export const mapOfFilters: Record<DataSource, QueryAdditionalFilter[]> = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const commonFormulaFilters: QueryAdditionalFilter[] = [
|
||||||
|
{
|
||||||
|
text: 'Having',
|
||||||
|
field: 'having',
|
||||||
|
},
|
||||||
|
{ text: 'Order by', field: 'orderBy' },
|
||||||
|
{ text: 'Limit', field: 'limit' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const mapOfFormulaToFilters: Record<
|
||||||
|
DataSource,
|
||||||
|
QueryAdditionalFilter[]
|
||||||
|
> = {
|
||||||
|
metrics: commonFormulaFilters,
|
||||||
|
logs: commonFormulaFilters,
|
||||||
|
traces: commonFormulaFilters,
|
||||||
|
};
|
||||||
|
|
||||||
export const REDUCE_TO_VALUES: SelectOption<ReduceOperators, string>[] = [
|
export const REDUCE_TO_VALUES: SelectOption<ReduceOperators, string>[] = [
|
||||||
{ value: 'last', label: 'Latest of values in timeframe' },
|
{ value: 'last', label: 'Latest of values in timeframe' },
|
||||||
{ value: 'sum', label: 'Sum of values in timeframe' },
|
{ value: 'sum', label: 'Sum of values in timeframe' },
|
||||||
|
@ -2,6 +2,7 @@ import { LeftOutlined, RightOutlined } from '@ant-design/icons';
|
|||||||
import { Button, Select } from 'antd';
|
import { Button, Select } from 'antd';
|
||||||
import { DEFAULT_PER_PAGE_OPTIONS, Pagination } from 'hooks/queryPagination';
|
import { DEFAULT_PER_PAGE_OPTIONS, Pagination } from 'hooks/queryPagination';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import { defaultSelectStyle } from './config';
|
import { defaultSelectStyle } from './config';
|
||||||
import { Container } from './styles';
|
import { Container } from './styles';
|
||||||
@ -51,6 +52,7 @@ function Controls({
|
|||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
value={countPerPage}
|
value={countPerPage}
|
||||||
onChange={handleCountItemsPerPageChange}
|
onChange={handleCountItemsPerPageChange}
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
>
|
>
|
||||||
{perPageOptions.map((count) => (
|
{perPageOptions.map((count) => (
|
||||||
<Select.Option
|
<Select.Option
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import './styles.scss';
|
||||||
|
|
||||||
import { Button, Divider, Space, Typography } from 'antd';
|
import { Button, Divider, Space, Typography } from 'antd';
|
||||||
import getNextPrevId from 'api/errors/getNextPrevId';
|
import getNextPrevId from 'api/errors/getNextPrevId';
|
||||||
import Editor from 'components/Editor';
|
import Editor from 'components/Editor';
|
||||||
@ -161,7 +163,9 @@ function ErrorDetails(props: ErrorDetailsProps): JSX.Element {
|
|||||||
</DashedContainer>
|
</DashedContainer>
|
||||||
|
|
||||||
<Typography.Title level={4}>{t('stack_trace')}</Typography.Title>
|
<Typography.Title level={4}>{t('stack_trace')}</Typography.Title>
|
||||||
<Editor onChange={(): void => {}} value={stackTraceValue} readOnly />
|
<div className="error-container">
|
||||||
|
<Editor value={stackTraceValue} readOnly />
|
||||||
|
</div>
|
||||||
|
|
||||||
<EditorContainer>
|
<EditorContainer>
|
||||||
<Space direction="vertical">
|
<Space direction="vertical">
|
||||||
|
3
frontend/src/container/ErrorDetails/styles.scss
Normal file
3
frontend/src/container/ErrorDetails/styles.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.error-container {
|
||||||
|
height: 50vh;
|
||||||
|
}
|
@ -20,6 +20,7 @@ import { ErrorResponse, SuccessResponse } from 'types/api';
|
|||||||
import { Widgets } from 'types/api/dashboard/getAll';
|
import { Widgets } from 'types/api/dashboard/getAll';
|
||||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||||
import AppReducer from 'types/reducer/app';
|
import AppReducer from 'types/reducer/app';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
errorTooltipPosition,
|
errorTooltipPosition,
|
||||||
@ -177,6 +178,7 @@ function WidgetHeader({
|
|||||||
return (
|
return (
|
||||||
<WidgetHeaderContainer>
|
<WidgetHeaderContainer>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
destroyPopupOnHide
|
destroyPopupOnHide
|
||||||
open={isOpen}
|
open={isOpen}
|
||||||
onOpenChange={setIsOpen}
|
onOpenChange={setIsOpen}
|
||||||
|
@ -34,6 +34,7 @@ import AppActions from 'types/actions';
|
|||||||
import { GET_ALL_DASHBOARD_SUCCESS } from 'types/actions/dashboard';
|
import { GET_ALL_DASHBOARD_SUCCESS } from 'types/actions/dashboard';
|
||||||
import { Dashboard } from 'types/api/dashboard/getAll';
|
import { Dashboard } from 'types/api/dashboard/getAll';
|
||||||
import AppReducer from 'types/reducer/app';
|
import AppReducer from 'types/reducer/app';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import ImportJSON from './ImportJSON';
|
import ImportJSON from './ImportJSON';
|
||||||
import { ButtonContainer, NewDashboardButton, TableContainer } from './styles';
|
import { ButtonContainer, NewDashboardButton, TableContainer } from './styles';
|
||||||
@ -280,6 +281,7 @@ function ListOfAllDashboard(): JSX.Element {
|
|||||||
/>
|
/>
|
||||||
{newDashboard && (
|
{newDashboard && (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
disabled={isDashboardListLoading}
|
disabled={isDashboardListLoading}
|
||||||
trigger={['click']}
|
trigger={['click']}
|
||||||
menu={menu}
|
menu={menu}
|
||||||
|
@ -11,6 +11,7 @@ import PopoverContent from 'pages/Logs/PopoverContent';
|
|||||||
import { useEventSource } from 'providers/EventSource';
|
import { useEventSource } from 'providers/EventSource';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { DataSource, StringOperators } from 'types/common/queryBuilder';
|
import { DataSource, StringOperators } from 'types/common/queryBuilder';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import { SpinnerWrapper, Wrapper } from './styles';
|
import { SpinnerWrapper, Wrapper } from './styles';
|
||||||
|
|
||||||
@ -43,6 +44,7 @@ function ListViewPanel(): JSX.Element {
|
|||||||
return (
|
return (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<Select
|
<Select
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
style={defaultSelectStyle}
|
style={defaultSelectStyle}
|
||||||
value={config.format?.value}
|
value={config.format?.value}
|
||||||
onChange={config.format?.onChange}
|
onChange={config.format?.onChange}
|
||||||
@ -53,7 +55,11 @@ function ListViewPanel(): JSX.Element {
|
|||||||
</Select>
|
</Select>
|
||||||
|
|
||||||
{isFormatButtonVisible && (
|
{isFormatButtonVisible && (
|
||||||
<Popover placement="right" content={renderPopoverContent}>
|
<Popover
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
|
placement="right"
|
||||||
|
content={renderPopoverContent}
|
||||||
|
>
|
||||||
<Button>Format</Button>
|
<Button>Format</Button>
|
||||||
</Popover>
|
</Popover>
|
||||||
)}
|
)}
|
||||||
|
@ -2,7 +2,7 @@ import {
|
|||||||
initialQueriesMap,
|
initialQueriesMap,
|
||||||
initialQueryBuilderFormValuesMap,
|
initialQueryBuilderFormValuesMap,
|
||||||
} from 'constants/queryBuilder';
|
} from 'constants/queryBuilder';
|
||||||
import { FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
|
import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
|
||||||
import {
|
import {
|
||||||
BaseAutocompleteData,
|
BaseAutocompleteData,
|
||||||
DataTypes,
|
DataTypes,
|
||||||
@ -14,7 +14,7 @@ export const defaultLiveQueryDataConfig: Partial<IBuilderQuery> = {
|
|||||||
aggregateOperator: LogsAggregatorOperator.NOOP,
|
aggregateOperator: LogsAggregatorOperator.NOOP,
|
||||||
disabled: true,
|
disabled: true,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
orderBy: [{ columnName: 'timestamp', order: FILTERS.DESC }],
|
orderBy: [{ columnName: 'timestamp', order: ORDERBY_FILTERS.DESC }],
|
||||||
};
|
};
|
||||||
|
|
||||||
type GetDefaultCompositeQueryParams = {
|
type GetDefaultCompositeQueryParams = {
|
||||||
|
@ -198,6 +198,7 @@ export const aggregateAttributesResourcesToString = (logData: ILog): string => {
|
|||||||
traceId: logData.traceId,
|
traceId: logData.traceId,
|
||||||
attributes: {},
|
attributes: {},
|
||||||
resources: {},
|
resources: {},
|
||||||
|
severity_text: logData.severity_text,
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.keys(logData).forEach((key) => {
|
Object.keys(logData).forEach((key) => {
|
||||||
|
@ -30,6 +30,7 @@ import { TLogsLiveTailState } from 'types/api/logs/liveTail';
|
|||||||
import { ILog } from 'types/api/logs/log';
|
import { ILog } from 'types/api/logs/log';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
import { ILogsReducer } from 'types/reducer/logs';
|
import { ILogsReducer } from 'types/reducer/logs';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import { TIME_PICKER_OPTIONS } from './config';
|
import { TIME_PICKER_OPTIONS } from './config';
|
||||||
import { StopContainer, TimePickerCard, TimePickerSelect } from './styles';
|
import { StopContainer, TimePickerCard, TimePickerSelect } from './styles';
|
||||||
@ -165,6 +166,7 @@ function LogLiveTail({ getLogsAggregate }: Props): JSX.Element {
|
|||||||
const OptionsPopOverContent = useMemo(
|
const OptionsPopOverContent = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<TimePickerSelect
|
<TimePickerSelect
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
disabled={liveTail === 'PLAYING'}
|
disabled={liveTail === 'PLAYING'}
|
||||||
value={liveTailStartRange}
|
value={liveTailStartRange}
|
||||||
onChange={(value): void => {
|
onChange={(value): void => {
|
||||||
@ -236,6 +238,7 @@ function LogLiveTail({ getLogsAggregate }: Props): JSX.Element {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<Popover
|
<Popover
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
placement="bottomRight"
|
placement="bottomRight"
|
||||||
title="Select Live Tail Timing"
|
title="Select Live Tail Timing"
|
||||||
trigger="click"
|
trigger="click"
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
import { Button, Form, Input, Space, Tooltip, Typography } from 'antd';
|
import { Button, Form, Input, Space, Tooltip, Typography } from 'antd';
|
||||||
import setLocalStorageApi from 'api/browser/localstorage/set';
|
|
||||||
import getUserVersion from 'api/user/getVersion';
|
import getUserVersion from 'api/user/getVersion';
|
||||||
import loginApi from 'api/user/login';
|
import loginApi from 'api/user/login';
|
||||||
import loginPrecheckApi from 'api/user/loginPrecheck';
|
import loginPrecheckApi from 'api/user/loginPrecheck';
|
||||||
import afterLogin from 'AppRoutes/utils';
|
import afterLogin from 'AppRoutes/utils';
|
||||||
import { FeatureKeys } from 'constants/features';
|
|
||||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import useFeatureFlag from 'hooks/useFeatureFlag';
|
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
@ -42,9 +38,6 @@ function Login({
|
|||||||
const { t } = useTranslation(['login']);
|
const { t } = useTranslation(['login']);
|
||||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||||
const { user } = useSelector<AppState, AppReducer>((state) => state.app);
|
const { user } = useSelector<AppState, AppReducer>((state) => state.app);
|
||||||
const isChatSupportEnabled: boolean | undefined = useFeatureFlag(
|
|
||||||
FeatureKeys.CHAT_SUPPORT,
|
|
||||||
)?.active;
|
|
||||||
|
|
||||||
const [precheckResult, setPrecheckResult] = useState<PrecheckResultType>({
|
const [precheckResult, setPrecheckResult] = useState<PrecheckResultType>({
|
||||||
sso: false,
|
sso: false,
|
||||||
@ -165,21 +158,12 @@ function Login({
|
|||||||
password,
|
password,
|
||||||
});
|
});
|
||||||
if (response.statusCode === 200) {
|
if (response.statusCode === 200) {
|
||||||
const user = await afterLogin(
|
await afterLogin(
|
||||||
response.payload.userId,
|
response.payload.userId,
|
||||||
response.payload.accessJwt,
|
response.payload.accessJwt,
|
||||||
response.payload.refreshJwt,
|
response.payload.refreshJwt,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (user) {
|
|
||||||
setLocalStorageApi(LOCALSTORAGE.LOGGED_IN_USER_NAME, user.payload?.name);
|
|
||||||
setLocalStorageApi(LOCALSTORAGE.LOGGED_IN_USER_EMAIL, user.payload?.email);
|
|
||||||
setLocalStorageApi(
|
|
||||||
LOCALSTORAGE.CHAT_SUPPORT,
|
|
||||||
(isChatSupportEnabled || '').toString(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
history.push(ROUTES.APPLICATION);
|
history.push(ROUTES.APPLICATION);
|
||||||
} else {
|
} else {
|
||||||
notifications.error({
|
notifications.error({
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Button, Typography } from 'antd';
|
import { Button, Typography } from 'antd';
|
||||||
import { FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
|
import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
|
||||||
|
|
||||||
import { ShowButtonWrapper } from './styles';
|
import { ShowButtonWrapper } from './styles';
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ function ShowButton({
|
|||||||
return (
|
return (
|
||||||
<ShowButtonWrapper>
|
<ShowButtonWrapper>
|
||||||
<Typography>
|
<Typography>
|
||||||
Showing 10 lines {order === FILTERS.ASC ? 'after' : 'before'} match
|
Showing 10 lines {order === ORDERBY_FILTERS.ASC ? 'after' : 'before'} match
|
||||||
</Typography>
|
</Typography>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import RawLogView from 'components/Logs/RawLogView';
|
import RawLogView from 'components/Logs/RawLogView';
|
||||||
import Spinner from 'components/Spinner';
|
import Spinner from 'components/Spinner';
|
||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
import { FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
|
import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
|
||||||
import { useGetExplorerQueryRange } from 'hooks/queryBuilder/useGetExplorerQueryRange';
|
import { useGetExplorerQueryRange } from 'hooks/queryBuilder/useGetExplorerQueryRange';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
@ -87,7 +87,7 @@ function LogsContextList({
|
|||||||
timestamp: item.timestamp,
|
timestamp: item.timestamp,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (order === FILTERS.ASC) {
|
if (order === ORDERBY_FILTERS.ASC) {
|
||||||
const reversedCurrentLogs = currentLogs.reverse();
|
const reversedCurrentLogs = currentLogs.reverse();
|
||||||
setLogs((prevLogs) => [...reversedCurrentLogs, ...prevLogs]);
|
setLogs((prevLogs) => [...reversedCurrentLogs, ...prevLogs]);
|
||||||
} else {
|
} else {
|
||||||
@ -111,7 +111,7 @@ function LogsContextList({
|
|||||||
const handleShowNextLines = useCallback(() => {
|
const handleShowNextLines = useCallback(() => {
|
||||||
if (isDisabledFetch) return;
|
if (isDisabledFetch) return;
|
||||||
|
|
||||||
const log = order === FILTERS.ASC ? firstLog : lastLog;
|
const log = order === ORDERBY_FILTERS.ASC ? firstLog : lastLog;
|
||||||
|
|
||||||
const newRequestData = getRequestData({
|
const newRequestData = getRequestData({
|
||||||
stagedQueryData: currentStagedQueryData,
|
stagedQueryData: currentStagedQueryData,
|
||||||
@ -167,7 +167,7 @@ function LogsContextList({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{order === FILTERS.ASC && (
|
{order === ORDERBY_FILTERS.ASC && (
|
||||||
<ShowButton
|
<ShowButton
|
||||||
isLoading={isFetching}
|
isLoading={isFetching}
|
||||||
isDisabled={isDisabledFetch}
|
isDisabled={isDisabledFetch}
|
||||||
@ -186,11 +186,11 @@ function LogsContextList({
|
|||||||
initialTopMostItemIndex={0}
|
initialTopMostItemIndex={0}
|
||||||
data={logs}
|
data={logs}
|
||||||
itemContent={getItemContent}
|
itemContent={getItemContent}
|
||||||
followOutput={order === FILTERS.DESC}
|
followOutput={order === ORDERBY_FILTERS.DESC}
|
||||||
/>
|
/>
|
||||||
</ListContainer>
|
</ListContainer>
|
||||||
|
|
||||||
{order === FILTERS.DESC && (
|
{order === ORDERBY_FILTERS.DESC && (
|
||||||
<ShowButton
|
<ShowButton
|
||||||
isLoading={isFetching}
|
isLoading={isFetching}
|
||||||
isDisabled={isDisabledFetch}
|
isDisabled={isDisabledFetch}
|
||||||
|
@ -3,7 +3,7 @@ import { Typography } from 'antd';
|
|||||||
import Modal from 'antd/es/modal/Modal';
|
import Modal from 'antd/es/modal/Modal';
|
||||||
import RawLogView from 'components/Logs/RawLogView';
|
import RawLogView from 'components/Logs/RawLogView';
|
||||||
import LogsContextList from 'container/LogsContextList';
|
import LogsContextList from 'container/LogsContextList';
|
||||||
import { FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
|
import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
|
||||||
import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch';
|
import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import { memo, useCallback, useState } from 'react';
|
import { memo, useCallback, useState } from 'react';
|
||||||
@ -87,7 +87,7 @@ function LogsExplorerContext({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<LogsContextList
|
<LogsContextList
|
||||||
order={FILTERS.ASC}
|
order={ORDERBY_FILTERS.ASC}
|
||||||
filters={filters}
|
filters={filters}
|
||||||
isEdit={isEdit}
|
isEdit={isEdit}
|
||||||
log={log}
|
log={log}
|
||||||
@ -103,7 +103,7 @@ function LogsExplorerContext({
|
|||||||
/>
|
/>
|
||||||
</LogContainer>
|
</LogContainer>
|
||||||
<LogsContextList
|
<LogsContextList
|
||||||
order={FILTERS.DESC}
|
order={ORDERBY_FILTERS.DESC}
|
||||||
filters={filters}
|
filters={filters}
|
||||||
isEdit={isEdit}
|
isEdit={isEdit}
|
||||||
log={log}
|
log={log}
|
||||||
|
@ -20,6 +20,7 @@ import {
|
|||||||
} from 'types/actions/logs';
|
} from 'types/actions/logs';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
import { ILogsReducer } from 'types/reducer/logs';
|
import { ILogsReducer } from 'types/reducer/logs';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import SearchFields from './SearchFields';
|
import SearchFields from './SearchFields';
|
||||||
import { Container, DropDownContainer } from './styles';
|
import { Container, DropDownContainer } from './styles';
|
||||||
@ -174,6 +175,7 @@ function SearchFilter({
|
|||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Popover
|
<Popover
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
content={
|
content={
|
||||||
<DropDownContainer>
|
<DropDownContainer>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import './GoLang.styles.scss';
|
import './GoLang.styles.scss';
|
||||||
|
|
||||||
import { MDXProvider } from '@mdx-js/react';
|
|
||||||
import { Form, Input } from 'antd';
|
import { Form, Input } from 'antd';
|
||||||
|
import { Code, Pre } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||||
import Header from 'container/OnboardingContainer/common/Header/Header';
|
import Header from 'container/OnboardingContainer/common/Header/Header';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
|
||||||
import ConnectionStatus from '../common/ConnectionStatus/ConnectionStatus';
|
import ConnectionStatus from '../common/ConnectionStatus/ConnectionStatus';
|
||||||
import GoLangDocs from './goLang.md';
|
import GoLangDocs from './goLang.md';
|
||||||
@ -44,9 +45,14 @@ export default function GoLang({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="content-container">
|
<div className="content-container">
|
||||||
<MDXProvider>
|
<ReactMarkdown
|
||||||
<GoLangDocs />
|
components={{
|
||||||
</MDXProvider>
|
pre: Pre,
|
||||||
|
code: Code,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{GoLangDocs}
|
||||||
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
From VMs, there are two ways to send data to SigNoz Cloud.
|
From VMs, there are two ways to send data to SigNoz Cloud.
|
||||||
|
|
||||||
- [Send traces directly to SigNoz Cloud](#send-traces-directly-to-signoz-cloud)
|
- Send traces directly to SigNoz Cloud (quick start)
|
||||||
- [Send traces via OTel Collector binary](#send-traces-via-otel-collector-binary) (recommended)
|
- Send traces via OTel Collector binary (recommended)
|
||||||
|
|
||||||
#### **Send traces directly to SigNoz Cloud**
|
#### **Send traces directly to SigNoz Cloud**
|
||||||
|
|
||||||
1. **Install Dependencies**<br></br>
|
1. **Install Dependencies**
|
||||||
|
|
||||||
Dependencies related to OpenTelemetry exporter and SDK have to be installed first. Note that we are assuming you are using `gin` request router. If you are using other request routers, check out the [corresponding package](#request-routers).
|
Dependencies related to OpenTelemetry exporter and SDK have to be installed first. Note that we are assuming you are using `gin` request router. If you are using other request routers, check out the [corresponding package](https://signoz.io/docs/instrumentation/golang/#request-routers).
|
||||||
|
|
||||||
Run the below commands after navigating to the application source folder:
|
Run the below commands after navigating to the application source folder:
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ From VMs, there are two ways to send data to SigNoz Cloud.
|
|||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Declare environment variables for configuring OpenTelemetry**<br></br>
|
2. **Declare environment variables for configuring OpenTelemetry**
|
||||||
|
|
||||||
Declare the following global variables in `main.go` which we will use to configure OpenTelemetry:
|
Declare the following global variables in `main.go` which we will use to configure OpenTelemetry:
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ From VMs, there are two ways to send data to SigNoz Cloud.
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Instrument your Go application with OpenTelemetry**<br></br>
|
3. **Instrument your Go application with OpenTelemetry**
|
||||||
|
|
||||||
To configure your application to send data we will need a function to initialize OpenTelemetry. Add the following snippet of code in your `main.go` file.
|
To configure your application to send data we will need a function to initialize OpenTelemetry. Add the following snippet of code in your `main.go` file.
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ From VMs, there are two ways to send data to SigNoz Cloud.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
4. **Initialize the tracer in main.go**<br></br>
|
4. **Initialize the tracer in main.go**
|
||||||
|
|
||||||
Modify the main function to initialise the tracer in `main.go`. Initiate the tracer at the very beginning of our main function.
|
Modify the main function to initialise the tracer in `main.go`. Initiate the tracer at the very beginning of our main function.
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ From VMs, there are two ways to send data to SigNoz Cloud.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
5. **Add the OpenTelemetry Gin middleware**<br></br>
|
5. **Add the OpenTelemetry Gin middleware**
|
||||||
|
|
||||||
Configure Gin to use the middleware by adding the following lines in `main.go`.
|
Configure Gin to use the middleware by adding the following lines in `main.go`.
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ From VMs, there are two ways to send data to SigNoz Cloud.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
6. **Set environment variables and run your Go Gin application**<br></br>
|
6. **Set environment variables and run your Go Gin application**
|
||||||
|
|
||||||
The run command must have some environment variables to send data to SigNoz cloud. The run command:
|
The run command must have some environment variables to send data to SigNoz cloud. The run command:
|
||||||
|
|
||||||
@ -143,14 +143,14 @@ From VMs, there are two ways to send data to SigNoz Cloud.
|
|||||||
|
|
||||||
`OTEL_EXPORTER_OTLP_HEADERS`: `signoz-access-token=<SIGNOZ-INGESTION-TOKEN>`. Update `<SIGNOZ-INGESTION-TOKEN>` with the ingestion token provided by SigNoz
|
`OTEL_EXPORTER_OTLP_HEADERS`: `signoz-access-token=<SIGNOZ-INGESTION-TOKEN>`. Update `<SIGNOZ-INGESTION-TOKEN>` with the ingestion token provided by SigNoz
|
||||||
|
|
||||||
`OTEL_EXPORTER_OTLP_ENDPOINT`: ingest.{region}.signoz.cloud:443. Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
`OTEL_EXPORTER_OTLP_ENDPOINT`: ingest.{region}.signoz.cloud:443. Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary accordingly.
|
||||||
|
|
||||||
|
|
||||||
US - ingest.us.signoz.cloud:443 <br></br>
|
US - ingest.us.signoz.cloud:443
|
||||||
|
|
||||||
IN - ingest.in.signoz.cloud:443 <br></br>
|
IN - ingest.in.signoz.cloud:443
|
||||||
|
|
||||||
EU - ingest.eu.signoz.cloud:443 <br></br>
|
EU - ingest.eu.signoz.cloud:443
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -161,9 +161,9 @@ OTel Collector binary helps to collect logs, hostmetrics, resource and infra att
|
|||||||
|
|
||||||
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Golang application.
|
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Golang application.
|
||||||
|
|
||||||
1. **Install Dependencies**<br></br>
|
1. **Install Dependencies**
|
||||||
|
|
||||||
Dependencies related to OpenTelemetry exporter and SDK have to be installed first. Note that we are assuming you are using `gin` request router. If you are using other request routers, check out the [corresponding package](#request-routers).
|
Dependencies related to OpenTelemetry exporter and SDK have to be installed first. Note that we are assuming you are using `gin` request router. If you are using other request routers, check out the [corresponding package](https://signoz.io/docs/instrumentation/golang/#request-routers).
|
||||||
|
|
||||||
Run the below commands after navigating to the application source folder:
|
Run the below commands after navigating to the application source folder:
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ You can find instructions to install OTel Collector binary [here](https://signoz
|
|||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Declare environment variables for configuring OpenTelemetry**<br></br>
|
2. **Declare environment variables for configuring OpenTelemetry**
|
||||||
|
|
||||||
Declare the following global variables in `main.go` which we will use to configure OpenTelemetry:
|
Declare the following global variables in `main.go` which we will use to configure OpenTelemetry:
|
||||||
|
|
||||||
@ -188,7 +188,7 @@ You can find instructions to install OTel Collector binary [here](https://signoz
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Instrument your Go application with OpenTelemetry**<br></br>
|
3. **Instrument your Go application with OpenTelemetry**
|
||||||
|
|
||||||
To configure your application to send data we will need a function to initialize OpenTelemetry. Add the following snippet of code in your `main.go` file.
|
To configure your application to send data we will need a function to initialize OpenTelemetry. Add the following snippet of code in your `main.go` file.
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ You can find instructions to install OTel Collector binary [here](https://signoz
|
|||||||
return exporter.Shutdown
|
return exporter.Shutdown
|
||||||
}
|
}
|
||||||
|
|
||||||
4. **Initialize the tracer in main.go**<br></br>
|
4. **Initialize the tracer in main.go**
|
||||||
|
|
||||||
Modify the main function to initialise the tracer in `main.go`. Initiate the tracer at the very beginning of our main function.
|
Modify the main function to initialise the tracer in `main.go`. Initiate the tracer at the very beginning of our main function.
|
||||||
|
|
||||||
@ -262,7 +262,7 @@ You can find instructions to install OTel Collector binary [here](https://signoz
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
5. **Add the OpenTelemetry Gin middleware**<br></br>
|
5. **Add the OpenTelemetry Gin middleware**
|
||||||
|
|
||||||
Configure Gin to use the middleware by adding the following lines in `main.go`.
|
Configure Gin to use the middleware by adding the following lines in `main.go`.
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ You can find instructions to install OTel Collector binary [here](https://signoz
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
6. **Set environment variables and run your Go Gin application**<br></br>
|
6. **Set environment variables and run your Go Gin application**
|
||||||
|
|
||||||
The run command must have some environment variables to send data to SigNoz. The run command:
|
The run command must have some environment variables to send data to SigNoz. The run command:
|
||||||
|
|
||||||
@ -288,20 +288,20 @@ You can find instructions to install OTel Collector binary [here](https://signoz
|
|||||||
SERVICE_NAME=goGinApp INSECURE_MODE=true OTEL_EXPORTER_OTLP_ENDPOINT=localhost:4317 go run main.go
|
SERVICE_NAME=goGinApp INSECURE_MODE=true OTEL_EXPORTER_OTLP_ENDPOINT=localhost:4317 go run main.go
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to update your `service_name`, you can modify the `SERVICE_NAME` variable.<br></br>
|
If you want to update your `service_name`, you can modify the `SERVICE_NAME` variable.
|
||||||
`SERVICE_NAME`: goGinApp (you can name it whatever you want)
|
`SERVICE_NAME`: goGinApp (you can name it whatever you want)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Applications Deployed on Kubernetes
|
### Applications Deployed on Kubernetes
|
||||||
|
|
||||||
For Golang application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](/docs/tutorial/kubernetes-infra-metrics/).
|
For Golang application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](https://signoz.io/docs/tutorial/kubernetes-infra-metrics/).
|
||||||
|
|
||||||
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Golang instrumentation by following the below steps:
|
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Golang instrumentation by following the below steps:
|
||||||
|
|
||||||
1. **Install Dependencies**<br></br>
|
1. **Install Dependencies**
|
||||||
|
|
||||||
Dependencies related to OpenTelemetry exporter and SDK have to be installed first. Note that we are assuming you are using `gin` request router. If you are using other request routers, check out the [corresponding package](#request-routers).
|
Dependencies related to OpenTelemetry exporter and SDK have to be installed first. Note that we are assuming you are using `gin` request router. If you are using other request routers, check out the [corresponding package](https://signoz.io/docs/instrumentation/golang/#request-routers).
|
||||||
|
|
||||||
Run the below commands after navigating to the application source folder:
|
Run the below commands after navigating to the application source folder:
|
||||||
|
|
||||||
@ -314,7 +314,7 @@ Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Go
|
|||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Declare environment variables for configuring OpenTelemetry**<br></br>
|
2. **Declare environment variables for configuring OpenTelemetry**
|
||||||
|
|
||||||
Declare the following global variables in `main.go` which we will use to configure OpenTelemetry:
|
Declare the following global variables in `main.go` which we will use to configure OpenTelemetry:
|
||||||
|
|
||||||
@ -326,7 +326,7 @@ Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Go
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Instrument your Go application with OpenTelemetry**<br></br>
|
3. **Instrument your Go application with OpenTelemetry**
|
||||||
|
|
||||||
To configure your application to send data we will need a function to initialize OpenTelemetry. Add the following snippet of code in your `main.go` file.
|
To configure your application to send data we will need a function to initialize OpenTelemetry. Add the following snippet of code in your `main.go` file.
|
||||||
|
|
||||||
@ -387,7 +387,7 @@ Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Go
|
|||||||
return exporter.Shutdown
|
return exporter.Shutdown
|
||||||
}
|
}
|
||||||
|
|
||||||
4. **Initialize the tracer in main.go**<br></br>
|
4. **Initialize the tracer in main.go**
|
||||||
|
|
||||||
Modify the main function to initialise the tracer in `main.go`. Initiate the tracer at the very beginning of our main function.
|
Modify the main function to initialise the tracer in `main.go`. Initiate the tracer at the very beginning of our main function.
|
||||||
|
|
||||||
@ -400,7 +400,7 @@ Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Go
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
5. **Add the OpenTelemetry Gin middleware**<br></br>
|
5. **Add the OpenTelemetry Gin middleware**
|
||||||
|
|
||||||
Configure Gin to use the middleware by adding the following lines in `main.go`.
|
Configure Gin to use the middleware by adding the following lines in `main.go`.
|
||||||
|
|
||||||
@ -418,7 +418,7 @@ Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Go
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
6. **Set environment variables and run your Go Gin application**<br></br>
|
6. **Set environment variables and run your Go Gin application**
|
||||||
|
|
||||||
The run command must have some environment variables to send data to SigNoz. The run command:
|
The run command must have some environment variables to send data to SigNoz. The run command:
|
||||||
|
|
||||||
@ -426,5 +426,5 @@ Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Go
|
|||||||
SERVICE_NAME=goGinApp INSECURE_MODE=true OTEL_EXPORTER_OTLP_ENDPOINT=localhost:4317 go run main.go
|
SERVICE_NAME=goGinApp INSECURE_MODE=true OTEL_EXPORTER_OTLP_ENDPOINT=localhost:4317 go run main.go
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to update your `service_name`, you can modify the `SERVICE_NAME` variable.<br></br>
|
If you want to update your `service_name`, you can modify the `SERVICE_NAME` variable.
|
||||||
`SERVICE_NAME`: goGinApp (you can name it whatever you want)
|
`SERVICE_NAME`: goGinApp (you can name it whatever you want)
|
@ -1,10 +1,12 @@
|
|||||||
import './Java.styles.scss';
|
import './Java.styles.scss';
|
||||||
|
|
||||||
import { MDXProvider } from '@mdx-js/react';
|
|
||||||
import { Form, Input, Select } from 'antd';
|
import { Form, Input, Select } from 'antd';
|
||||||
|
import { Code, Pre } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||||
import Header from 'container/OnboardingContainer/common/Header/Header';
|
import Header from 'container/OnboardingContainer/common/Header/Header';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
import { trackEvent } from 'utils/segmentAnalytics';
|
import { trackEvent } from 'utils/segmentAnalytics';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import ConnectionStatus from '../common/ConnectionStatus/ConnectionStatus';
|
import ConnectionStatus from '../common/ConnectionStatus/ConnectionStatus';
|
||||||
import JavaDocs from './md-docs/java.md';
|
import JavaDocs from './md-docs/java.md';
|
||||||
@ -25,7 +27,9 @@ export default function Java({
|
|||||||
activeStep: number;
|
activeStep: number;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const [selectedFrameWork, setSelectedFrameWork] = useState('spring_boot');
|
const [selectedFrameWork, setSelectedFrameWork] = useState('spring_boot');
|
||||||
|
const [selectedFrameWorkDocs, setSelectedFrameWorkDocs] = useState(
|
||||||
|
SprintBootDocs,
|
||||||
|
);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -36,16 +40,22 @@ export default function Java({
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [selectedFrameWork]);
|
}, [selectedFrameWork]);
|
||||||
|
|
||||||
const renderDocs = (): JSX.Element => {
|
const handleFrameworkChange = (selectedFrameWork: string): void => {
|
||||||
|
setSelectedFrameWork(selectedFrameWork);
|
||||||
|
|
||||||
switch (selectedFrameWork) {
|
switch (selectedFrameWork) {
|
||||||
case 'tomcat':
|
case 'tomcat':
|
||||||
return <TomcatDocs />;
|
setSelectedFrameWorkDocs(TomcatDocs);
|
||||||
|
break;
|
||||||
case 'spring_boot':
|
case 'spring_boot':
|
||||||
return <SprintBootDocs />;
|
setSelectedFrameWorkDocs(SprintBootDocs);
|
||||||
|
break;
|
||||||
case 'jboss':
|
case 'jboss':
|
||||||
return <JbossDocs />;
|
setSelectedFrameWorkDocs(JbossDocs);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return <JavaDocs />;
|
setSelectedFrameWorkDocs(JavaDocs);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,10 +76,11 @@ export default function Java({
|
|||||||
<div className="label"> Select Framework </div>
|
<div className="label"> Select Framework </div>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
defaultValue="spring_boot"
|
defaultValue="spring_boot"
|
||||||
style={{ minWidth: 120 }}
|
style={{ minWidth: 120 }}
|
||||||
placeholder="Select Framework"
|
placeholder="Select Framework"
|
||||||
onChange={(value): void => setSelectedFrameWork(value)}
|
onChange={(value): void => handleFrameworkChange(value)}
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
value: 'spring_boot',
|
value: 'spring_boot',
|
||||||
@ -108,7 +119,14 @@ export default function Java({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="content-container">
|
<div className="content-container">
|
||||||
<MDXProvider>{renderDocs()}</MDXProvider>
|
<ReactMarkdown
|
||||||
|
components={{
|
||||||
|
pre: Pre,
|
||||||
|
code: Code,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{selectedFrameWorkDocs}
|
||||||
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -12,8 +12,8 @@ Based on your application environment, you can choose the setup below to send tr
|
|||||||
|
|
||||||
From VMs, there are two ways to send data to SigNoz Cloud.
|
From VMs, there are two ways to send data to SigNoz Cloud.
|
||||||
|
|
||||||
- [Send traces directly to SigNoz Cloud](#send-traces-directly-to-signoz-cloud)
|
- Send traces directly to SigNoz Cloud (quick start)
|
||||||
- [Send traces via OTel Collector binary](#send-traces-via-otel-collector-binary) (recommended)
|
- Send traces via OTel Collector binary (recommended)
|
||||||
|
|
||||||
#### **Send traces directly to SigNoz Cloud**
|
#### **Send traces directly to SigNoz Cloud**
|
||||||
|
|
||||||
@ -29,21 +29,22 @@ Step 2. Run your application
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<app_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<app_name> \
|
||||||
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=SIGNOZ_INGESTION_KEY" \
|
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=<SIGNOZ_INGESTION_KEY>" \
|
||||||
OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.{region}.signoz.cloud:443 \
|
OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.{region}.signoz.cloud:443 \
|
||||||
java -javaagent:$PWD/opentelemetry-javaagent.jar -jar <my-app>.jar
|
java -javaagent:<path>/opentelemetry-javaagent.jar -jar <my-app>.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<app_name>` is the name for your application
|
- `<app_name>` is the name for your application
|
||||||
- `SIGNOZ_INGESTION_KEY` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
- `<SIGNOZ_INGESTION_KEY>` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
||||||
|
- `path` - Update it to the path of your downloaded Java JAR agent.
|
||||||
|
|
||||||
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
||||||
|
|
||||||
US - ingest.us.signoz.cloud:443 <br></br>
|
US - ingest.us.signoz.cloud:443
|
||||||
|
|
||||||
IN - ingest.in.signoz.cloud:443 <br></br>
|
IN - ingest.in.signoz.cloud:443
|
||||||
|
|
||||||
EU - ingest.eu.signoz.cloud:443 <br></br>
|
EU - ingest.eu.signoz.cloud:443
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -54,43 +55,43 @@ OTel Collector binary helps to collect logs, hostmetrics, resource and infra att
|
|||||||
|
|
||||||
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Java application.
|
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Java application.
|
||||||
|
|
||||||
Step 1. Download OTel java binary agent<br></br>
|
Step 1. Download OTel java binary agent
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 2. Run your application<br></br>
|
Step 2. Run your application
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
java -javaagent:$PWD/opentelemetry-javaagent.jar -jar <myapp>.jar
|
java -javaagent:<path>/opentelemetry-javaagent.jar -jar <myapp>.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<myapp>` is the name of your application jar file
|
- `<myapp>` is the name of your application jar file
|
||||||
- In case you download `opentelemetry-javaagent.jar` file in different directory than that of the project, replace `$PWD` with the path of the otel jar file.
|
- `path` - Update it to the path of your downloaded Java JAR agent.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Applications Deployed on Kubernetes
|
### Applications Deployed on Kubernetes
|
||||||
|
|
||||||
For Java application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](/docs/tutorial/kubernetes-infra-metrics/).
|
For Java application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](https://signoz.io/docs/tutorial/kubernetes-infra-metrics/).
|
||||||
|
|
||||||
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry java instrumentation by following the below steps:
|
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry java instrumentation by following the below steps:
|
||||||
|
|
||||||
1. Download otel java binary<br></br>
|
Step 1. Download otel java binary
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Run your application<br></br>
|
Step 2. Run your application
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
java -javaagent:$PWD/opentelemetry-javaagent.jar -jar <myapp>.jar
|
java -javaagent:<path>/opentelemetry-javaagent.jar -jar <myapp>.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<myapp>` is the name of your application jar file
|
- `<myapp>` is the name of your application jar file
|
||||||
- In case you download `opentelemetry-javaagent.jar` file in different directory than that of the project, replace `$PWD` with the path of the otel jar file.
|
- `path` - Update it to the path of your downloaded Java JAR agent.
|
||||||
|
|
||||||
3. Make sure to dockerise your application along with OpenTelemetry instrumentation.
|
Step 3. Make sure to dockerise your application along with OpenTelemetry instrumentation.
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ Based on your application environment, you can choose the setup below to send tr
|
|||||||
|
|
||||||
From VMs, there are two ways to send data to SigNoz Cloud.
|
From VMs, there are two ways to send data to SigNoz Cloud.
|
||||||
|
|
||||||
- [Send traces directly to SigNoz Cloud](#send-traces-directly-to-signoz-cloud)
|
- Send traces directly to SigNoz Cloud (quick start)
|
||||||
- [Send traces via OTel Collector binary](#send-traces-via-otel-collector-binary) (recommended)
|
- Send traces via OTel Collector binary (recommended)
|
||||||
|
|
||||||
#### **Send traces directly to SigNoz Cloud**
|
#### **Send traces directly to SigNoz Cloud**
|
||||||
OpenTelemetry Java agent can send traces directly to SigNoz Cloud.
|
OpenTelemetry Java agent can send traces directly to SigNoz Cloud.
|
||||||
@ -35,25 +35,25 @@ Step 3. Update `JAVA_OPTS` environment variable
|
|||||||
Update `JAVA_OPTS` environment variable with configurations required to send data to SigNoz cloud in your configuration file.
|
Update `JAVA_OPTS` environment variable with configurations required to send data to SigNoz cloud in your configuration file.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
JAVA_OPTS="-javaagent:/path/opentelemetry-javaagent.jar
|
JAVA_OPTS="-javaagent:/<path>/opentelemetry-javaagent.jar
|
||||||
-Dotel.exporter.otlp.endpoint=https://ingest.{region}.signoz.cloud:443
|
-Dotel.exporter.otlp.endpoint=https://ingest.{region}.signoz.cloud:443
|
||||||
-Dotel.exporter.otlp.headers="signoz-access-token=SIGNOZ_INGESTION_KEY"
|
-Dotel.exporter.otlp.headers="signoz-access-token=<SIGNOZ_INGESTION_KEY>"
|
||||||
-Dotel.resource.attributes="service.name=<app_name>""
|
-Dotel.resource.attributes="service.name=<app_name>""
|
||||||
```
|
```
|
||||||
You need to replace the following things based on your environment:<br></br>
|
You need to replace the following things based on your environment:
|
||||||
|
|
||||||
- `path` - Update it to the path of your downloaded Java JAR agent.<br></br>
|
- `<path>` - Update it to the path of your downloaded Java JAR agent.
|
||||||
- `<app_name>` is the name for your application
|
- `<app_name>` is the name for your application
|
||||||
- `SIGNOZ_INGESTION_KEY` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
- `<SIGNOZ_INGESTION_KEY>` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
||||||
|
|
||||||
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
||||||
|
|
||||||
|
|
||||||
US - ingest.us.signoz.cloud:443 <br></br>
|
US - ingest.us.signoz.cloud:443
|
||||||
|
|
||||||
IN - ingest.in.signoz.cloud:443 <br></br>
|
IN - ingest.in.signoz.cloud:443
|
||||||
|
|
||||||
EU - ingest.eu.signoz.cloud:443 <br></br>
|
EU - ingest.eu.signoz.cloud:443
|
||||||
|
|
||||||
|
|
||||||
Step 4. [Optional] Write the output/logs of standalone.sh script to a file nohup.out as a background thread
|
Step 4. [Optional] Write the output/logs of standalone.sh script to a file nohup.out as a background thread
|
||||||
@ -69,7 +69,7 @@ OTel Collector binary helps to collect logs, hostmetrics, resource and infra att
|
|||||||
|
|
||||||
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Java application.
|
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Java application.
|
||||||
|
|
||||||
Step 1. Download OTel java binary agent<br></br>
|
Step 1. Download OTel java binary agent
|
||||||
```bash
|
```bash
|
||||||
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
||||||
```
|
```
|
||||||
@ -90,17 +90,17 @@ JAVA_OPTS="-javaagent:/path/opentelemetry-javaagent.jar"
|
|||||||
```
|
```
|
||||||
|
|
||||||
where,
|
where,
|
||||||
- `path` - Update it to the path of your downloaded Java JAR agent.<br></br>
|
- `path` - Update it to the path of your downloaded Java JAR agent.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Applications Deployed on Kubernetes
|
### Applications Deployed on Kubernetes
|
||||||
|
|
||||||
For Java application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](/docs/tutorial/kubernetes-infra-metrics/).
|
For Java application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](https://signoz.io/docs/tutorial/kubernetes-infra-metrics/).
|
||||||
|
|
||||||
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry java instrumentation by following the below steps:
|
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry java instrumentation by following the below steps:
|
||||||
|
|
||||||
Step 1. Download otel java binary<br></br>
|
Step 1. Download otel java binary
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
||||||
@ -121,7 +121,7 @@ JAVA_OPTS="-javaagent:/path/opentelemetry-javaagent.jar"
|
|||||||
```
|
```
|
||||||
|
|
||||||
where,
|
where,
|
||||||
- `path` - Update it to the path of your downloaded Java JAR agent.<br></br>
|
- `path` - Update it to the path of your downloaded Java JAR agent.
|
||||||
|
|
||||||
|
|
||||||
Step 4. Make sure to dockerise your application along with OpenTelemetry instrumentation.
|
Step 4. Make sure to dockerise your application along with OpenTelemetry instrumentation.
|
@ -12,8 +12,8 @@ Based on your application environment, you can choose the setup below to send tr
|
|||||||
|
|
||||||
From VMs, there are two ways to send data to SigNoz Cloud.
|
From VMs, there are two ways to send data to SigNoz Cloud.
|
||||||
|
|
||||||
- [Send traces directly to SigNoz Cloud](#send-traces-directly-to-signoz-cloud)
|
- Send traces directly to SigNoz Cloud (quick start)
|
||||||
- [Send traces via OTel Collector binary](#send-traces-via-otel-collector-binary) (recommended)
|
- Send traces via OTel Collector binary (recommended)
|
||||||
|
|
||||||
#### **Send traces directly to SigNoz Cloud**
|
#### **Send traces directly to SigNoz Cloud**
|
||||||
OpenTelemetry Java agent can send traces directly to SigNoz Cloud.
|
OpenTelemetry Java agent can send traces directly to SigNoz Cloud.
|
||||||
@ -27,21 +27,22 @@ wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releas
|
|||||||
Step 2. Run your application
|
Step 2. Run your application
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<app_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<myapp> \
|
||||||
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=SIGNOZ_INGESTION_KEY" \
|
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=<SIGNOZ_INGESTION_KEY>" \
|
||||||
OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.{region}.signoz.cloud:443 \
|
OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.{region}.signoz.cloud:443 \
|
||||||
java -javaagent:$PWD/opentelemetry-javaagent.jar -jar <my-app>.jar
|
java -javaagent:<path>/opentelemetry-javaagent.jar -jar <myapp>.jar
|
||||||
```
|
```
|
||||||
- `<app_name>` is the name for your application
|
- `<myapp>` is the name for your application
|
||||||
- `SIGNOZ_INGESTION_KEY` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
- `<path>` - update it to the path of your downloaded Java JAR agent
|
||||||
|
- `<SIGNOZ_INGESTION_KEY>` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
||||||
|
|
||||||
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
||||||
|
|
||||||
US - ingest.us.signoz.cloud:443 <br></br>
|
US - ingest.us.signoz.cloud:443
|
||||||
|
|
||||||
IN - ingest.in.signoz.cloud:443 <br></br>
|
IN - ingest.in.signoz.cloud:443
|
||||||
|
|
||||||
EU - ingest.eu.signoz.cloud:443 <br></br>
|
EU - ingest.eu.signoz.cloud:443
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -51,41 +52,41 @@ OTel Collector binary helps to collect logs, hostmetrics, resource and infra att
|
|||||||
|
|
||||||
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Java application.
|
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Java application.
|
||||||
|
|
||||||
Step 1. Download OTel java binary agent<br></br>
|
Step 1. Download OTel java binary agent
|
||||||
```bash
|
```bash
|
||||||
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 2. Run your application<br></br>
|
Step 2. Run your application
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
java -javaagent:$PWD/opentelemetry-javaagent.jar -jar <myapp>.jar
|
java -javaagent:<path>/opentelemetry-javaagent.jar -jar <myapp>.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<myapp>` is the name of your application jar file
|
- `<myapp>` is the name of your application
|
||||||
- In case you download `opentelemetry-javaagent.jar` file in different directory than that of the project, replace `$PWD` with the path of the otel jar file.
|
- `<path>` - update it to the path of your downloaded Java JAR agent
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Applications Deployed on Kubernetes
|
### Applications Deployed on Kubernetes
|
||||||
|
|
||||||
For Java application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](/docs/tutorial/kubernetes-infra-metrics/).
|
For Java application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](https://signoz.io/docs/tutorial/kubernetes-infra-metrics/).
|
||||||
|
|
||||||
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry java instrumentation by following the below steps:
|
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry java instrumentation by following the below steps:
|
||||||
|
|
||||||
1. Download otel java binary<br></br>
|
Step 1. Download otel java binary
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Run your application<br></br>
|
Step 2. Run your application
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
java -javaagent:$PWD/opentelemetry-javaagent.jar -jar <myapp>.jar
|
java -javaagent:<path>/opentelemetry-javaagent.jar -jar <myapp>.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<myapp>` is the name of your application jar file
|
- `<myapp>` is the name of your application
|
||||||
- In case you download `opentelemetry-javaagent.jar` file in different directory than that of the project, replace `$PWD` with the path of the otel jar file.
|
- `<path>` - update it to the path of your downloaded Java JAR agent
|
||||||
|
|
||||||
3. Make sure to dockerise your application along with OpenTelemetry instrumentation.
|
Step 3. Make sure to dockerise your application along with OpenTelemetry instrumentation.
|
@ -12,8 +12,8 @@ Based on your application environment, you can choose the setup below to send tr
|
|||||||
|
|
||||||
From VMs, there are two ways to send data to SigNoz Cloud.
|
From VMs, there are two ways to send data to SigNoz Cloud.
|
||||||
|
|
||||||
- [Send traces directly to SigNoz Cloud](#send-traces-directly-to-signoz-cloud)
|
- Send traces directly to SigNoz Cloud (quick start)
|
||||||
- [Send traces via OTel Collector binary](#send-traces-via-otel-collector-binary) (recommended)
|
- Send traces via OTel Collector binary (recommended)
|
||||||
|
|
||||||
#### **Send traces directly to SigNoz Cloud**
|
#### **Send traces directly to SigNoz Cloud**
|
||||||
OpenTelemetry Java agent can send traces directly to SigNoz Cloud.
|
OpenTelemetry Java agent can send traces directly to SigNoz Cloud.
|
||||||
@ -26,28 +26,27 @@ wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releas
|
|||||||
|
|
||||||
Step 2. Enable the instrumentation agent and run your application
|
Step 2. Enable the instrumentation agent and run your application
|
||||||
|
|
||||||
If you run your `.war` package by putting in `webapps` folder, just add `setenv.sh` in your Tomcat `bin` folder.
|
If you run your `.war` package by putting in `webapps` folder, just add `setenv.sh` in your Tomcat `bin` folder. Inside the `setenv.sh` file, add the following environment variables:
|
||||||
|
|
||||||
This should set these environment variables and start sending telemetry data to SigNoz Cloud.
|
|
||||||
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export CATALINA_OPTS="$CATALINA_OPTS -javaagent:/path/to/opentelemetry-javaagent.jar"
|
export CATALINA_OPTS="$CATALINA_OPTS -javaagent:/<path>/opentelemetry-javaagent.jar"
|
||||||
export OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=SIGNOZ_INGESTION_KEY"
|
export OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=<SIGNOZ_INGESTION_KEY>"
|
||||||
export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.{region}.signoz.cloud:443
|
export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.{region}.signoz.cloud:443
|
||||||
export OTEL_RESOURCE_ATTRIBUTES=service.name=<app_name>
|
export OTEL_RESOURCE_ATTRIBUTES=service.name=<app_name>
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<app_name>` is the name for your application
|
- `<app_name>` is the name for your application
|
||||||
- `SIGNOZ_INGESTION_KEY` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
- `<path>` - update it to the path of your downloaded Java JAR agent.
|
||||||
|
- `<SIGNOZ_INGESTION_KEY>` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
||||||
|
|
||||||
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary accordingly.
|
||||||
|
|
||||||
US - ingest.us.signoz.cloud:443 <br></br>
|
US - ingest.us.signoz.cloud:443
|
||||||
|
|
||||||
IN - ingest.in.signoz.cloud:443 <br></br>
|
IN - ingest.in.signoz.cloud:443
|
||||||
|
|
||||||
EU - ingest.eu.signoz.cloud:443 <br></br>
|
EU - ingest.eu.signoz.cloud:443
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -57,12 +56,12 @@ OTel Collector binary helps to collect logs, hostmetrics, resource and infra att
|
|||||||
|
|
||||||
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Java application.
|
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Java application.
|
||||||
|
|
||||||
Step 1. Download OTel java binary agent<br></br>
|
Step 1. Download OTel java binary agent
|
||||||
```bash
|
```bash
|
||||||
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 2. Enable the instrumentation agent and run your application<br></br>
|
Step 2. Enable the instrumentation agent and run your application
|
||||||
|
|
||||||
If you run your `.war` package by putting in `webapps` folder, just add `setenv.sh` in your Tomcat `bin` folder.
|
If you run your `.war` package by putting in `webapps` folder, just add `setenv.sh` in your Tomcat `bin` folder.
|
||||||
|
|
||||||
@ -70,37 +69,37 @@ This should set these environment variables and start sending telemetry data to
|
|||||||
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export CATALINA_OPTS="$CATALINA_OPTS -javaagent:/path/to/opentelemetry-javaagent.jar"
|
export CATALINA_OPTS="$CATALINA_OPTS -javaagent:/<path>/opentelemetry-javaagent.jar"
|
||||||
```
|
```
|
||||||
|
|
||||||
- path/to - Update it to the path of your downloaded Java JAR agent.
|
- `<path>` - Update it to the path of your downloaded Java JAR agent.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Applications Deployed on Kubernetes
|
### Applications Deployed on Kubernetes
|
||||||
|
|
||||||
For Java application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](/docs/tutorial/kubernetes-infra-metrics/).
|
For Java application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](https://signoz.io/docs/tutorial/kubernetes-infra-metrics/).
|
||||||
|
|
||||||
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry java instrumentation by following the below steps:
|
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry java instrumentation by following the below steps:
|
||||||
|
|
||||||
1. Download otel java binary<br></br>
|
Step 1. Download otel java binary
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Enable the instrumentation agent and run your application<br></br>
|
Step 2. Enable the instrumentation agent and run your application
|
||||||
|
|
||||||
If you run your `.war` package by putting in `webapps` folder, just add `setenv.sh` in your Tomcat `bin` folder.
|
If you run your `.war` package by putting in `webapps` folder, just add `setenv.sh` in your Tomcat `bin` folder.
|
||||||
|
|
||||||
This should set the environment variable and start sending telemetry data to SigNoz Cloud.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export CATALINA_OPTS="$CATALINA_OPTS -javaagent:/path/to/opentelemetry-javaagent.jar"
|
|
||||||
```
|
|
||||||
|
|
||||||
- path/to - Update it to the path of your downloaded Java JAR agent.
|
This should set the environment variable and start sending telemetry data to SigNoz Cloud.
|
||||||
|
|
||||||
3. Make sure to dockerise your application along with OpenTelemetry instrumentation.
|
```bash
|
||||||
|
export CATALINA_OPTS="$CATALINA_OPTS -javaagent:/<path>/opentelemetry-javaagent.jar"
|
||||||
|
```
|
||||||
|
|
||||||
You can validate if your application is sending traces to SigNoz cloud by following the instructions [here](#validating-instrumentation-by-checking-for-traces).
|
- `<path>` - Update it to the path of your downloaded Java JAR agent.
|
||||||
|
|
||||||
|
Step 3. Make sure to dockerise your application along with OpenTelemetry instrumentation.
|
||||||
|
|
||||||
|
You can validate if your application is sending traces to SigNoz cloud by following the instructions [here](https://signoz.io/docs/instrumentation/tomcat/#validating-instrumentation-by-checking-for-traces).
|
@ -1,10 +1,12 @@
|
|||||||
import './Javascript.styles.scss';
|
import './Javascript.styles.scss';
|
||||||
|
|
||||||
import { MDXProvider } from '@mdx-js/react';
|
|
||||||
import { Form, Input, Select } from 'antd';
|
import { Form, Input, Select } from 'antd';
|
||||||
|
import { Code, Pre } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||||
import Header from 'container/OnboardingContainer/common/Header/Header';
|
import Header from 'container/OnboardingContainer/common/Header/Header';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
import { trackEvent } from 'utils/segmentAnalytics';
|
import { trackEvent } from 'utils/segmentAnalytics';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import ConnectionStatus from '../common/ConnectionStatus/ConnectionStatus';
|
import ConnectionStatus from '../common/ConnectionStatus/ConnectionStatus';
|
||||||
import ExpressDocs from './md-docs/express.md';
|
import ExpressDocs from './md-docs/express.md';
|
||||||
@ -22,8 +24,10 @@ export default function Javascript({
|
|||||||
}: {
|
}: {
|
||||||
activeStep: number;
|
activeStep: number;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const [selectedFrameWork, setSelectedFrameWork] = useState('nodejs');
|
const [selectedFrameWork, setSelectedFrameWork] = useState('express');
|
||||||
|
const [selectedFrameWorkDocs, setSelectedFrameWorkDocs] = useState(
|
||||||
|
ExpressDocs,
|
||||||
|
);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -34,14 +38,19 @@ export default function Javascript({
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [selectedFrameWork]);
|
}, [selectedFrameWork]);
|
||||||
|
|
||||||
const renderDocs = (): JSX.Element => {
|
const handleFrameworkChange = (selectedFrameWork: string): void => {
|
||||||
|
setSelectedFrameWork(selectedFrameWork);
|
||||||
|
|
||||||
switch (selectedFrameWork) {
|
switch (selectedFrameWork) {
|
||||||
case 'nodejs':
|
case 'nodejs':
|
||||||
return <JavascriptDocs />;
|
setSelectedFrameWorkDocs(JavascriptDocs);
|
||||||
|
break;
|
||||||
case 'nestjs':
|
case 'nestjs':
|
||||||
return <NestJsDocs />;
|
setSelectedFrameWorkDocs(NestJsDocs);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return <ExpressDocs />;
|
setSelectedFrameWorkDocs(ExpressDocs);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,10 +71,11 @@ export default function Javascript({
|
|||||||
<div className="label"> Select Framework </div>
|
<div className="label"> Select Framework </div>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
defaultValue="express"
|
defaultValue="express"
|
||||||
style={{ minWidth: 120 }}
|
style={{ minWidth: 120 }}
|
||||||
placeholder="Select Framework"
|
placeholder="Select Framework"
|
||||||
onChange={(value): void => setSelectedFrameWork(value)}
|
onChange={(value): void => handleFrameworkChange(value)}
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
value: 'nodejs',
|
value: 'nodejs',
|
||||||
@ -106,7 +116,14 @@ export default function Javascript({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="content-container">
|
<div className="content-container">
|
||||||
<MDXProvider>{renderDocs()}</MDXProvider>
|
<ReactMarkdown
|
||||||
|
components={{
|
||||||
|
pre: Pre,
|
||||||
|
code: Code,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{selectedFrameWorkDocs}
|
||||||
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -1,213 +1,212 @@
|
|||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
Supported Versions
|
Supported Versions
|
||||||
|
|
||||||
^4.0.0
|
^4.0.0
|
||||||
|
|
||||||
## Send traces to SigNoz Cloud
|
## Send traces to SigNoz Cloud
|
||||||
|
|
||||||
Based on your application environment, you can choose the setup below to send traces to SigNoz Cloud.
|
Based on your application environment, you can choose the setup below to send traces to SigNoz Cloud.
|
||||||
|
|
||||||
### Application on VMs
|
### Application on VMs
|
||||||
|
|
||||||
From VMs, there are two ways to send data to SigNoz Cloud.
|
From VMs, there are two ways to send data to SigNoz Cloud.
|
||||||
|
|
||||||
- [Send traces directly to SigNoz Cloud](#send-traces-directly-to-signoz-cloud)
|
- Send traces directly to SigNoz Cloud (quick start)
|
||||||
- [Send traces via OTel Collector binary](#send-traces-via-otel-collector-binary) (recommended)
|
- Send traces via OTel Collector binary(recommended)
|
||||||
|
|
||||||
#### **Send traces directly to SigNoz Cloud**
|
#### **Send traces directly to SigNoz Cloud**
|
||||||
|
|
||||||
Step 1. Install OpenTelemetry packages
|
Step 1. Install OpenTelemetry packages
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install --save @opentelemetry/api@^1.4.1
|
npm install --save @opentelemetry/api@^1.4.1
|
||||||
npm install --save @opentelemetry/sdk-node@^0.39.1
|
npm install --save @opentelemetry/sdk-node@^0.39.1
|
||||||
npm install --save @opentelemetry/auto-instrumentations-node@^0.37.0
|
npm install --save @opentelemetry/auto-instrumentations-node@^0.37.0
|
||||||
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 2. Create tracing.js file<br></br>
|
Step 2. Create tracing.js file
|
||||||
|
|
||||||
You need to configure the endpoint for SigNoz cloud in this file. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
You need to configure the endpoint for SigNoz cloud in this file. You also need to configure your service name. In this example, we have used `node_app`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// tracing.js
|
// tracing.js
|
||||||
'use strict'
|
'use strict'
|
||||||
const process = require('process');
|
const process = require('process');
|
||||||
const opentelemetry = require('@opentelemetry/sdk-node');
|
const opentelemetry = require('@opentelemetry/sdk-node');
|
||||||
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
|
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
|
||||||
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
|
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
|
||||||
const { Resource } = require('@opentelemetry/resources');
|
const { Resource } = require('@opentelemetry/resources');
|
||||||
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
|
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
|
||||||
|
|
||||||
// do not set headers in exporterOptions, the OTel spec recommends setting headers through ENV variables
|
// do not set headers in exporterOptions, the OTel spec recommends setting headers through ENV variables
|
||||||
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#specifying-headers-via-environment-variables
|
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#specifying-headers-via-environment-variables
|
||||||
|
|
||||||
// highlight-start
|
const exporterOptions = {
|
||||||
const exporterOptions = {
|
url: 'https://ingest.{region}.signoz.cloud:443/v1/traces'
|
||||||
url: 'https://ingest.{region}.signoz.cloud:443/v1/traces'
|
}
|
||||||
}
|
|
||||||
// highlight-end
|
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
||||||
|
const sdk = new opentelemetry.NodeSDK({
|
||||||
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
traceExporter,
|
||||||
const sdk = new opentelemetry.NodeSDK({
|
instrumentations: [getNodeAutoInstrumentations()],
|
||||||
traceExporter,
|
resource: new Resource({
|
||||||
instrumentations: [getNodeAutoInstrumentations()],
|
[SemanticResourceAttributes.SERVICE_NAME]: 'node_app'
|
||||||
resource: new Resource({
|
})
|
||||||
// highlight-next-line
|
});
|
||||||
[SemanticResourceAttributes.SERVICE_NAME]: 'node_app'
|
|
||||||
})
|
// initialize the SDK and register with the OpenTelemetry API
|
||||||
});
|
// this enables the API to record telemetry
|
||||||
|
sdk.start()
|
||||||
// initialize the SDK and register with the OpenTelemetry API
|
|
||||||
// this enables the API to record telemetry
|
// gracefully shut down the SDK on process exit
|
||||||
sdk.start()
|
process.on('SIGTERM', () => {
|
||||||
|
sdk.shutdown()
|
||||||
// gracefully shut down the SDK on process exit
|
.then(() => console.log('Tracing terminated'))
|
||||||
process.on('SIGTERM', () => {
|
.catch((error) => console.log('Error terminating tracing', error))
|
||||||
sdk.shutdown()
|
.finally(() => process.exit(0));
|
||||||
.then(() => console.log('Tracing terminated'))
|
});
|
||||||
.catch((error) => console.log('Error terminating tracing', error))
|
```
|
||||||
.finally(() => process.exit(0));
|
|
||||||
});
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
||||||
```
|
|
||||||
|
US - ingest.us.signoz.cloud:443/v1/traces
|
||||||
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
|
||||||
|
IN - ingest.in.signoz.cloud:443/v1/traces
|
||||||
US - ingest.us.signoz.cloud:443/v1/traces <br></br>
|
|
||||||
|
EU - ingest.eu.signoz.cloud:443/v1/traces
|
||||||
IN - ingest.in.signoz.cloud:443/v1/traces <br></br>
|
|
||||||
|
Step 3. Run the application
|
||||||
EU - ingest.eu.signoz.cloud:443/v1/traces <br></br>
|
|
||||||
|
Make sure you set the `OTEL_EXPORTER_OTLP_HEADERS` env as follows
|
||||||
Step 3. Run the application<br></br>
|
```bash
|
||||||
|
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=<SIGNOZ_INGESTION_KEY>" node -r ./tracing.js app.js
|
||||||
Make sure you set the `OTEL_EXPORTER_OTLP_HEADERS` env as follows
|
```
|
||||||
```bash
|
|
||||||
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=<SIGNOZ_INGESTION_KEY>" node -r ./tracing.js app.js
|
`<SIGNOZ_INGESTION_KEY>` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
||||||
```
|
|
||||||
|
---
|
||||||
`SIGNOZ_INGESTION_KEY` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
|
||||||
|
#### **Send traces via OTel Collector binary**
|
||||||
---
|
|
||||||
|
OTel Collector binary helps to collect logs, hostmetrics, resource and infra attributes. It is recommended to install Otel Collector binary to collect and send traces to SigNoz cloud. You can correlate signals and have rich contextual data through this way.
|
||||||
#### **Send traces via OTel Collector binary**
|
|
||||||
|
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Javascript application.
|
||||||
OTel Collector binary helps to collect logs, hostmetrics, resource and infra attributes. It is recommended to install Otel Collector binary to collect and send traces to SigNoz cloud. You can correlate signals and have rich contextual data through this way.
|
|
||||||
|
|
||||||
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Javascript application.
|
Step 1. Install OpenTelemetry packages
|
||||||
|
|
||||||
|
```js
|
||||||
Step 1. Install OpenTelemetry packages
|
npm install --save @opentelemetry/api@^1.4.1
|
||||||
|
npm install --save @opentelemetry/sdk-node@^0.39.1
|
||||||
```js
|
npm install --save @opentelemetry/auto-instrumentations-node@^0.37.0
|
||||||
npm install --save @opentelemetry/api@^1.4.1
|
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
||||||
npm install --save @opentelemetry/sdk-node@^0.39.1
|
```
|
||||||
npm install --save @opentelemetry/auto-instrumentations-node@^0.37.0
|
|
||||||
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
Step 2. Create tracing.js file
|
||||||
```
|
|
||||||
|
You need to configure your service name. In this example, we have used `node_app`.
|
||||||
Step 2. Create tracing.js file<br></br>
|
|
||||||
|
```js
|
||||||
```js
|
// tracing.js
|
||||||
// tracing.js
|
'use strict'
|
||||||
'use strict'
|
const process = require('process');
|
||||||
const process = require('process');
|
const opentelemetry = require('@opentelemetry/sdk-node');
|
||||||
const opentelemetry = require('@opentelemetry/sdk-node');
|
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
|
||||||
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
|
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
|
||||||
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
|
const { Resource } = require('@opentelemetry/resources');
|
||||||
const { Resource } = require('@opentelemetry/resources');
|
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
|
||||||
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
|
|
||||||
|
const exporterOptions = {
|
||||||
const exporterOptions = {
|
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318/v1/traces',
|
||||||
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318/v1/traces',
|
}
|
||||||
}
|
|
||||||
|
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
||||||
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
const sdk = new opentelemetry.NodeSDK({
|
||||||
const sdk = new opentelemetry.NodeSDK({
|
traceExporter,
|
||||||
traceExporter,
|
instrumentations: [getNodeAutoInstrumentations()],
|
||||||
instrumentations: [getNodeAutoInstrumentations()],
|
resource: new Resource({
|
||||||
resource: new Resource({
|
[SemanticResourceAttributes.SERVICE_NAME]: 'node_app'
|
||||||
// highlight-next-line
|
})
|
||||||
[SemanticResourceAttributes.SERVICE_NAME]: 'node_app'
|
});
|
||||||
})
|
|
||||||
});
|
// initialize the SDK and register with the OpenTelemetry API
|
||||||
|
// this enables the API to record telemetry
|
||||||
// initialize the SDK and register with the OpenTelemetry API
|
sdk.start()
|
||||||
// this enables the API to record telemetry
|
|
||||||
sdk.start()
|
// gracefully shut down the SDK on process exit
|
||||||
|
process.on('SIGTERM', () => {
|
||||||
// gracefully shut down the SDK on process exit
|
sdk.shutdown()
|
||||||
process.on('SIGTERM', () => {
|
.then(() => console.log('Tracing terminated'))
|
||||||
sdk.shutdown()
|
.catch((error) => console.log('Error terminating tracing', error))
|
||||||
.then(() => console.log('Tracing terminated'))
|
.finally(() => process.exit(0));
|
||||||
.catch((error) => console.log('Error terminating tracing', error))
|
});
|
||||||
.finally(() => process.exit(0));
|
```
|
||||||
});
|
|
||||||
```
|
Step 3. Run the application
|
||||||
|
```bash
|
||||||
Step 3. Run the application<br></br>
|
node -r ./tracing.js app.js
|
||||||
```bash
|
```
|
||||||
node -r ./tracing.js app.js
|
---
|
||||||
```
|
|
||||||
---
|
### Applications Deployed on Kubernetes
|
||||||
|
|
||||||
### Applications Deployed on Kubernetes
|
For Javascript application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](https://signoz.io/docs/tutorial/kubernetes-infra-metrics/).
|
||||||
|
|
||||||
For Javascript application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](/docs/tutorial/kubernetes-infra-metrics/).
|
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Javascript instrumentation by following the below steps:
|
||||||
|
|
||||||
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Javascript instrumentation by following the below steps:
|
Step 1. Install OpenTelemetry packages
|
||||||
|
|
||||||
Step 1. Install OpenTelemetry packages
|
```bash
|
||||||
|
npm install --save @opentelemetry/api@^1.4.1
|
||||||
```bash
|
npm install --save @opentelemetry/sdk-node@^0.39.1
|
||||||
npm install --save @opentelemetry/api@^1.4.1
|
npm install --save @opentelemetry/auto-instrumentations-node@^0.37.0
|
||||||
npm install --save @opentelemetry/sdk-node@^0.39.1
|
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
||||||
npm install --save @opentelemetry/auto-instrumentations-node@^0.37.0
|
```
|
||||||
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
|
||||||
```
|
Step 2. Create tracing.js file
|
||||||
|
|
||||||
Step 2. Create tracing.js file<br></br>
|
You also need to configure your service name. In this example, we have used `node_app`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// tracing.js
|
// tracing.js
|
||||||
'use strict'
|
'use strict'
|
||||||
const process = require('process');
|
const process = require('process');
|
||||||
const opentelemetry = require('@opentelemetry/sdk-node');
|
const opentelemetry = require('@opentelemetry/sdk-node');
|
||||||
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
|
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
|
||||||
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
|
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
|
||||||
const { Resource } = require('@opentelemetry/resources');
|
const { Resource } = require('@opentelemetry/resources');
|
||||||
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
|
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
|
||||||
|
|
||||||
const exporterOptions = {
|
const exporterOptions = {
|
||||||
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318/v1/traces',
|
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318/v1/traces',
|
||||||
}
|
}
|
||||||
|
|
||||||
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
||||||
const sdk = new opentelemetry.NodeSDK({
|
const sdk = new opentelemetry.NodeSDK({
|
||||||
traceExporter,
|
traceExporter,
|
||||||
instrumentations: [getNodeAutoInstrumentations()],
|
instrumentations: [getNodeAutoInstrumentations()],
|
||||||
resource: new Resource({
|
resource: new Resource({
|
||||||
// highlight-next-line
|
[SemanticResourceAttributes.SERVICE_NAME]: 'node_app'
|
||||||
[SemanticResourceAttributes.SERVICE_NAME]: 'node_app'
|
})
|
||||||
})
|
});
|
||||||
});
|
|
||||||
|
// initialize the SDK and register with the OpenTelemetry API
|
||||||
// initialize the SDK and register with the OpenTelemetry API
|
// this enables the API to record telemetry
|
||||||
// this enables the API to record telemetry
|
sdk.start()
|
||||||
sdk.start()
|
|
||||||
|
// gracefully shut down the SDK on process exit
|
||||||
// gracefully shut down the SDK on process exit
|
process.on('SIGTERM', () => {
|
||||||
process.on('SIGTERM', () => {
|
sdk.shutdown()
|
||||||
sdk.shutdown()
|
.then(() => console.log('Tracing terminated'))
|
||||||
.then(() => console.log('Tracing terminated'))
|
.catch((error) => console.log('Error terminating tracing', error))
|
||||||
.catch((error) => console.log('Error terminating tracing', error))
|
.finally(() => process.exit(0));
|
||||||
.finally(() => process.exit(0));
|
});
|
||||||
});
|
```
|
||||||
```
|
|
||||||
|
Step 3. Run the application
|
||||||
Step 3. Run the application<br></br>
|
|
||||||
|
```bash
|
||||||
```bash
|
node -r ./tracing.js app.js
|
||||||
node -r ./tracing.js app.js
|
|
||||||
```
|
```
|
@ -1,6 +1,6 @@
|
|||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- Node.js version 14 or newer ([See here](https://github.com/open-telemetry/opentelemetry-js#supported-runtimes))<br></br>
|
- Node.js version 14 or newer ([See here](https://github.com/open-telemetry/opentelemetry-js#supported-runtimes))
|
||||||
|
|
||||||
## Send traces to SigNoz Cloud
|
## Send traces to SigNoz Cloud
|
||||||
|
|
||||||
@ -10,8 +10,8 @@ Based on your application environment, you can choose the setup below to send tr
|
|||||||
|
|
||||||
From VMs, there are two ways to send data to SigNoz Cloud.
|
From VMs, there are two ways to send data to SigNoz Cloud.
|
||||||
|
|
||||||
- [Send traces directly to SigNoz Cloud](#send-traces-directly-to-signoz-cloud)
|
- Send traces directly to SigNoz Cloud (quick start)
|
||||||
- [Send traces via OTel Collector binary](#send-traces-via-otel-collector-binary) (recommended)
|
- Send traces via OTel Collector binary (recommended)
|
||||||
|
|
||||||
#### **Send traces directly to SigNoz Cloud**
|
#### **Send traces directly to SigNoz Cloud**
|
||||||
|
|
||||||
@ -24,9 +24,9 @@ npm install --save @opentelemetry/auto-instrumentations-node@^0.37.0
|
|||||||
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 2. Create tracing.js file<br></br>
|
Step 2. Create tracing.js file
|
||||||
|
|
||||||
You need to configure the endpoint for SigNoz cloud in this file. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
You need to configure the endpoint for SigNoz cloud in this file. You also need to configure your service name. In this example, we have used `node_app`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// tracing.js
|
// tracing.js
|
||||||
@ -41,18 +41,15 @@ const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventi
|
|||||||
// do not set headers in exporterOptions, the OTel spec recommends setting headers through ENV variables
|
// do not set headers in exporterOptions, the OTel spec recommends setting headers through ENV variables
|
||||||
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#specifying-headers-via-environment-variables
|
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#specifying-headers-via-environment-variables
|
||||||
|
|
||||||
// highlight-start
|
|
||||||
const exporterOptions = {
|
const exporterOptions = {
|
||||||
url: 'https://ingest.{region}.signoz.cloud:443/v1/traces'
|
url: 'https://ingest.{region}.signoz.cloud:443/v1/traces'
|
||||||
}
|
}
|
||||||
// highlight-end
|
|
||||||
|
|
||||||
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
||||||
const sdk = new opentelemetry.NodeSDK({
|
const sdk = new opentelemetry.NodeSDK({
|
||||||
traceExporter,
|
traceExporter,
|
||||||
instrumentations: [getNodeAutoInstrumentations()],
|
instrumentations: [getNodeAutoInstrumentations()],
|
||||||
resource: new Resource({
|
resource: new Resource({
|
||||||
// highlight-next-line
|
|
||||||
[SemanticResourceAttributes.SERVICE_NAME]: 'node_app'
|
[SemanticResourceAttributes.SERVICE_NAME]: 'node_app'
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -72,13 +69,13 @@ process.on('SIGTERM', () => {
|
|||||||
|
|
||||||
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
||||||
|
|
||||||
US - ingest.us.signoz.cloud:443/v1/traces <br></br>
|
US - ingest.us.signoz.cloud:443/v1/traces
|
||||||
|
|
||||||
IN - ingest.in.signoz.cloud:443/v1/traces <br></br>
|
IN - ingest.in.signoz.cloud:443/v1/traces
|
||||||
|
|
||||||
EU - ingest.eu.signoz.cloud:443/v1/traces <br></br>
|
EU - ingest.eu.signoz.cloud:443/v1/traces
|
||||||
|
|
||||||
Step 3. Run the application<br></br>
|
Step 3. Run the application
|
||||||
|
|
||||||
Make sure you set the `OTEL_EXPORTER_OTLP_HEADERS` env as follows
|
Make sure you set the `OTEL_EXPORTER_OTLP_HEADERS` env as follows
|
||||||
|
|
||||||
@ -86,7 +83,7 @@ Make sure you set the `OTEL_EXPORTER_OTLP_HEADERS` env as follows
|
|||||||
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=<SIGNOZ_INGESTION_KEY>" node -r ./tracing.js app.js
|
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=<SIGNOZ_INGESTION_KEY>" node -r ./tracing.js app.js
|
||||||
```
|
```
|
||||||
|
|
||||||
`SIGNOZ_INGESTION_KEY` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
`<SIGNOZ_INGESTION_KEY>` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -105,7 +102,9 @@ npm install --save @opentelemetry/auto-instrumentations-node@^0.37.0
|
|||||||
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 2. Create tracing.js file<br></br>
|
Step 2. Create tracing.js file
|
||||||
|
|
||||||
|
You need to configure your service name. In this example, we have used `node_app`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// tracing.js
|
// tracing.js
|
||||||
@ -126,7 +125,6 @@ const sdk = new opentelemetry.NodeSDK({
|
|||||||
traceExporter,
|
traceExporter,
|
||||||
instrumentations: [getNodeAutoInstrumentations()],
|
instrumentations: [getNodeAutoInstrumentations()],
|
||||||
resource: new Resource({
|
resource: new Resource({
|
||||||
// highlight-next-line
|
|
||||||
[SemanticResourceAttributes.SERVICE_NAME]: 'node_app'
|
[SemanticResourceAttributes.SERVICE_NAME]: 'node_app'
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -144,7 +142,7 @@ process.on('SIGTERM', () => {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 3. Run the application<br></br>
|
Step 3. Run the application
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
node -r ./tracing.js app.js
|
node -r ./tracing.js app.js
|
||||||
@ -154,7 +152,7 @@ node -r ./tracing.js app.js
|
|||||||
|
|
||||||
### Applications Deployed on Kubernetes
|
### Applications Deployed on Kubernetes
|
||||||
|
|
||||||
For Javascript application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](/docs/tutorial/kubernetes-infra-metrics/).
|
For Javascript application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](https://signoz.io/docs/tutorial/kubernetes-infra-metrics/).
|
||||||
|
|
||||||
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Javascript instrumentation by following the below steps:
|
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Javascript instrumentation by following the below steps:
|
||||||
|
|
||||||
@ -167,7 +165,9 @@ npm install --save @opentelemetry/auto-instrumentations-node@^0.37.0
|
|||||||
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 2. Create tracing.js file<br></br>
|
Step 2. Create tracing.js file
|
||||||
|
|
||||||
|
You need to configure your service name. In this example, we have used `node_app`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// tracing.js
|
// tracing.js
|
||||||
@ -188,7 +188,6 @@ const sdk = new opentelemetry.NodeSDK({
|
|||||||
traceExporter,
|
traceExporter,
|
||||||
instrumentations: [getNodeAutoInstrumentations()],
|
instrumentations: [getNodeAutoInstrumentations()],
|
||||||
resource: new Resource({
|
resource: new Resource({
|
||||||
// highlight-next-line
|
|
||||||
[SemanticResourceAttributes.SERVICE_NAME]: 'node_app'
|
[SemanticResourceAttributes.SERVICE_NAME]: 'node_app'
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -206,7 +205,7 @@ process.on('SIGTERM', () => {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 3. Run the application<br></br>
|
Step 3. Run the application
|
||||||
```bash
|
```bash
|
||||||
node -r ./tracing.js app.js
|
node -r ./tracing.js app.js
|
||||||
```
|
```
|
@ -12,8 +12,8 @@ Based on your application environment, you can choose the setup below to send tr
|
|||||||
|
|
||||||
From VMs, there are two ways to send data to SigNoz Cloud.
|
From VMs, there are two ways to send data to SigNoz Cloud.
|
||||||
|
|
||||||
- [Send traces directly to SigNoz Cloud](#send-traces-directly-to-signoz-cloud)
|
- Send traces directly to SigNoz Cloud (quick start)
|
||||||
- [Send traces via OTel Collector binary](#send-traces-via-otel-collector-binary) (recommended)
|
- Send traces via OTel Collector binary (recommended)
|
||||||
|
|
||||||
#### **Send traces directly to SigNoz Cloud**
|
#### **Send traces directly to SigNoz Cloud**
|
||||||
|
|
||||||
@ -26,14 +26,13 @@ npm install --save @opentelemetry/auto-instrumentations-node@^0.37.0
|
|||||||
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 2. Create `tracer.ts` file<br></br>
|
Step 2. Create `tracer.ts` file
|
||||||
|
|
||||||
You need to configure the endpoint for SigNoz cloud in this file.
|
You need to configure the endpoint for SigNoz cloud in this file. You also need to configure your service name. In this example, we have used `sampleNestjsApplication`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
'use strict'
|
'use strict'
|
||||||
const process = require('process');
|
const process = require('process');
|
||||||
//OpenTelemetry
|
|
||||||
const opentelemetry = require('@opentelemetry/sdk-node');
|
const opentelemetry = require('@opentelemetry/sdk-node');
|
||||||
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
|
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
|
||||||
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
|
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
|
||||||
@ -41,9 +40,7 @@ const {Resource} = require('@opentelemetry/resources');
|
|||||||
const {SemanticResourceAttributes} = require('@opentelemetry/semantic-conventions');
|
const {SemanticResourceAttributes} = require('@opentelemetry/semantic-conventions');
|
||||||
|
|
||||||
const exporterOptions = {
|
const exporterOptions = {
|
||||||
// highlight-start
|
|
||||||
url: 'https://ingest.{region}.signoz.cloud:443/v1/traces'
|
url: 'https://ingest.{region}.signoz.cloud:443/v1/traces'
|
||||||
// highlight-end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
||||||
@ -70,26 +67,26 @@ const sdk = new opentelemetry.NodeSDK({
|
|||||||
module.exports = sdk
|
module.exports = sdk
|
||||||
```
|
```
|
||||||
|
|
||||||
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary accordingly.
|
||||||
|
|
||||||
US - ingest.us.signoz.cloud:443/v1/traces <br></br>
|
US - ingest.us.signoz.cloud:443/v1/traces
|
||||||
|
|
||||||
IN - ingest.in.signoz.cloud:443/v1/traces <br></br>
|
IN - ingest.in.signoz.cloud:443/v1/traces
|
||||||
|
|
||||||
EU - ingest.eu.signoz.cloud:443/v1/traces <br></br>
|
EU - ingest.eu.signoz.cloud:443/v1/traces
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Step 3. Import the tracer module where your app starts
|
Step 3. Import the tracer module where your app starts `(Ex —> main.ts)`
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
const tracer = require('./tracer')
|
const tracer = require('./tracer')
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Step 4. Start the tracer<br></br>
|
Step 4. Start the tracer
|
||||||
|
|
||||||
In the `async function boostrap` section of the application code, initialize the tracer as follows:
|
In the `async function boostrap` section of the application code `(Ex —> In main.ts)`, initialize the tracer as follows:
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
const tracer = require('./tracer')
|
const tracer = require('./tracer')
|
||||||
@ -100,9 +97,7 @@ import { AppModule } from './app.module';
|
|||||||
// OpenTelemetry automatic instrumentation must go here.
|
// OpenTelemetry automatic instrumentation must go here.
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
// highlight-start
|
|
||||||
await tracer.start();
|
await tracer.start();
|
||||||
//highlight-end
|
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
await app.listen(3001);
|
await app.listen(3001);
|
||||||
}
|
}
|
||||||
@ -117,7 +112,7 @@ OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=<SIGNOZ_INGESTION_KEY>" nest sta
|
|||||||
|
|
||||||
You can now run your Nestjs application. The data captured with OpenTelemetry from your application should start showing on the SigNoz dashboard.
|
You can now run your Nestjs application. The data captured with OpenTelemetry from your application should start showing on the SigNoz dashboard.
|
||||||
|
|
||||||
`SIGNOZ_INGESTION_KEY` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
`<SIGNOZ_INGESTION_KEY>` is the API token provided by SigNoz. You can find your ingestion key from SigNoz cloud account details sent on your email.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -136,7 +131,9 @@ npm install --save @opentelemetry/auto-instrumentations-node@^0.37.0
|
|||||||
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 2. Create `tracer.ts` file<br></br>
|
Step 2. Create `tracer.ts` file
|
||||||
|
|
||||||
|
You need to configure your service name. In this example, we have used `sampleNestjsApplication`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
'use strict'
|
'use strict'
|
||||||
@ -149,9 +146,7 @@ const {Resource} = require('@opentelemetry/resources');
|
|||||||
const {SemanticResourceAttributes} = require('@opentelemetry/semantic-conventions');
|
const {SemanticResourceAttributes} = require('@opentelemetry/semantic-conventions');
|
||||||
|
|
||||||
const exporterOptions = {
|
const exporterOptions = {
|
||||||
// highlight-start
|
|
||||||
url: 'http://localhost:4318/v1/traces'
|
url: 'http://localhost:4318/v1/traces'
|
||||||
// highlight-end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
||||||
@ -185,7 +180,7 @@ const tracer = require('./tracer')
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Step 4. Start the tracer<br></br>
|
Step 4. Start the tracer
|
||||||
|
|
||||||
In the `async function boostrap` section of the application code, initialize the tracer as follows:
|
In the `async function boostrap` section of the application code, initialize the tracer as follows:
|
||||||
|
|
||||||
@ -198,9 +193,7 @@ import { AppModule } from './app.module';
|
|||||||
// OpenTelemetry automatic instrumentation must go here.
|
// OpenTelemetry automatic instrumentation must go here.
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
// highlight-start
|
|
||||||
await tracer.start();
|
await tracer.start();
|
||||||
//highlight-end
|
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
await app.listen(3001);
|
await app.listen(3001);
|
||||||
}
|
}
|
||||||
@ -213,7 +206,7 @@ Step 5. Run the application
|
|||||||
|
|
||||||
### Applications Deployed on Kubernetes
|
### Applications Deployed on Kubernetes
|
||||||
|
|
||||||
For Javascript application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](/docs/tutorial/kubernetes-infra-metrics/).
|
For Javascript application deployed on Kubernetes, you need to install OTel Collector agent in your k8s infra to collect and send traces to SigNoz Cloud. You can find the instructions to install OTel Collector agent [here](https://signoz.io/docs/tutorial/kubernetes-infra-metrics/).
|
||||||
|
|
||||||
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Javascript instrumentation by following the below steps:
|
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Javascript instrumentation by following the below steps:
|
||||||
|
|
||||||
@ -226,7 +219,9 @@ npm install --save @opentelemetry/auto-instrumentations-node@^0.37.0
|
|||||||
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
npm install --save @opentelemetry/exporter-trace-otlp-http@^0.39.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 2. Create `tracer.ts` file<br></br>
|
Step 2. Create `tracer.ts` file
|
||||||
|
|
||||||
|
You need to configure your service name. In this example, we have used `sampleNestjsApplication`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
'use strict'
|
'use strict'
|
||||||
@ -239,9 +234,7 @@ const {Resource} = require('@opentelemetry/resources');
|
|||||||
const {SemanticResourceAttributes} = require('@opentelemetry/semantic-conventions');
|
const {SemanticResourceAttributes} = require('@opentelemetry/semantic-conventions');
|
||||||
|
|
||||||
const exporterOptions = {
|
const exporterOptions = {
|
||||||
// highlight-start
|
|
||||||
url: 'http://localhost:4318/v1/traces'
|
url: 'http://localhost:4318/v1/traces'
|
||||||
// highlight-end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
const traceExporter = new OTLPTraceExporter(exporterOptions);
|
||||||
@ -275,7 +268,7 @@ const tracer = require('./tracer')
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Step 4. Start the tracer<br></br>
|
Step 4. Start the tracer
|
||||||
|
|
||||||
In the `async function boostrap` section of the application code, initialize the tracer as follows:
|
In the `async function boostrap` section of the application code, initialize the tracer as follows:
|
||||||
|
|
||||||
@ -288,9 +281,7 @@ import { AppModule } from './app.module';
|
|||||||
// OpenTelemetry automatic instrumentation must go here.
|
// OpenTelemetry automatic instrumentation must go here.
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
// highlight-start
|
|
||||||
await tracer.start();
|
await tracer.start();
|
||||||
//highlight-end
|
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
await app.listen(3001);
|
await app.listen(3001);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import './Python.styles.scss';
|
import './Python.styles.scss';
|
||||||
|
|
||||||
import { MDXProvider } from '@mdx-js/react';
|
|
||||||
import { Form, Input, Select } from 'antd';
|
import { Form, Input, Select } from 'antd';
|
||||||
|
import { Code, Pre } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||||
import Header from 'container/OnboardingContainer/common/Header/Header';
|
import Header from 'container/OnboardingContainer/common/Header/Header';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
import { trackEvent } from 'utils/segmentAnalytics';
|
import { trackEvent } from 'utils/segmentAnalytics';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import ConnectionStatus from '../common/ConnectionStatus/ConnectionStatus';
|
import ConnectionStatus from '../common/ConnectionStatus/ConnectionStatus';
|
||||||
import DjangoDocs from './md-docs/django.md';
|
import DjangoDocs from './md-docs/django.md';
|
||||||
@ -27,7 +29,7 @@ export default function Python({
|
|||||||
activeStep: number;
|
activeStep: number;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const [selectedFrameWork, setSelectedFrameWork] = useState('django');
|
const [selectedFrameWork, setSelectedFrameWork] = useState('django');
|
||||||
|
const [selectedFrameWorkDocs, setSelectedFrameWorkDocs] = useState(DjangoDocs);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -38,18 +40,25 @@ export default function Python({
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [selectedFrameWork]);
|
}, [selectedFrameWork]);
|
||||||
|
|
||||||
const renderDocs = (): JSX.Element => {
|
const handleFrameworkChange = (selectedFrameWork: string): void => {
|
||||||
|
setSelectedFrameWork(selectedFrameWork);
|
||||||
|
|
||||||
switch (selectedFrameWork) {
|
switch (selectedFrameWork) {
|
||||||
case 'django':
|
case 'django':
|
||||||
return <DjangoDocs />;
|
setSelectedFrameWorkDocs(DjangoDocs);
|
||||||
|
break;
|
||||||
case 'fastAPI':
|
case 'fastAPI':
|
||||||
return <FastAPIDocs />;
|
setSelectedFrameWorkDocs(FastAPIDocs);
|
||||||
|
break;
|
||||||
case 'flask':
|
case 'flask':
|
||||||
return <FlaskDocs />;
|
setSelectedFrameWorkDocs(FlaskDocs);
|
||||||
|
break;
|
||||||
case 'falcon':
|
case 'falcon':
|
||||||
return <FalconDocs />;
|
setSelectedFrameWorkDocs(FalconDocs);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return <PythonDocs />;
|
setSelectedFrameWorkDocs(PythonDocs);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,10 +79,11 @@ export default function Python({
|
|||||||
<div className="label"> Select Framework </div>
|
<div className="label"> Select Framework </div>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
defaultValue="Django"
|
defaultValue="Django"
|
||||||
style={{ minWidth: 120 }}
|
style={{ minWidth: 120 }}
|
||||||
placeholder="Select Framework"
|
placeholder="Select Framework"
|
||||||
onChange={(value): void => setSelectedFrameWork(value)}
|
onChange={(value): void => handleFrameworkChange(value)}
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
value: 'django',
|
value: 'django',
|
||||||
@ -116,7 +126,14 @@ export default function Python({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="content-container">
|
<div className="content-container">
|
||||||
<MDXProvider>{renderDocs()}</MDXProvider>
|
<ReactMarkdown
|
||||||
|
components={{
|
||||||
|
pre: Pre,
|
||||||
|
code: Code,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{selectedFrameWorkDocs}
|
||||||
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -19,12 +19,12 @@ Based on your application environment, you can choose the setup below to send tr
|
|||||||
|
|
||||||
From VMs, there are two ways to send data to SigNoz Cloud.
|
From VMs, there are two ways to send data to SigNoz Cloud.
|
||||||
|
|
||||||
- [Send traces directly to SigNoz Cloud](#send-traces-directly-to-signoz-cloud)
|
- Send traces directly to SigNoz Cloud (quick start)
|
||||||
- [Send traces via OTel Collector binary](#send-traces-via-otel-collector-binary) (recommended)
|
- Send traces via OTel Collector binary (recommended)
|
||||||
|
|
||||||
#### **Send traces directly to SigNoz Cloud**
|
#### **Send traces directly to SigNoz Cloud**
|
||||||
|
|
||||||
Step 1. Create a virtual environment<br></br>
|
Step 1. Create a virtual environment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
@ -38,22 +38,6 @@ pip install opentelemetry-distro==0.38b0
|
|||||||
pip install opentelemetry-exporter-otlp==1.17.0
|
pip install opentelemetry-exporter-otlp==1.17.0
|
||||||
```
|
```
|
||||||
|
|
||||||
<!-- The dependencies included are briefly explained below:
|
|
||||||
|
|
||||||
`opentelemetry-distro` - The distro provides a mechanism to automatically configure some of the more common options for users. It helps to get started with OpenTelemetry auto-instrumentation quickly.
|
|
||||||
|
|
||||||
`opentelemetry-exporter-otlp` - This library provides a way to install all OTLP exporters. You will need an exporter to send the data to SigNoz.
|
|
||||||
|
|
||||||
:::note
|
|
||||||
💡 The `opentelemetry-exporter-otlp` is a convenience wrapper package to install all OTLP exporters. Currently, it installs:
|
|
||||||
|
|
||||||
- opentelemetry-exporter-otlp-proto-http
|
|
||||||
- opentelemetry-exporter-otlp-proto-grpc
|
|
||||||
|
|
||||||
- (soon) opentelemetry-exporter-otlp-json-http
|
|
||||||
|
|
||||||
The `opentelemetry-exporter-otlp-proto-grpc` package installs the gRPC exporter which depends on the `grpcio` package. The installation of `grpcio` may fail on some platforms for various reasons. If you run into such issues, or you don't want to use gRPC, you can install the HTTP exporter instead by installing the `opentelemetry-exporter-otlp-proto-http` package. You need to set the `OTEL_EXPORTER_OTLP_PROTOCOL` environment variable to `http/protobuf` to use the HTTP exporter.
|
|
||||||
::: -->
|
|
||||||
|
|
||||||
Step 3. Add automatic instrumentation
|
Step 3. Add automatic instrumentation
|
||||||
|
|
||||||
@ -68,22 +52,22 @@ Step 4. Run your application
|
|||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.{region}.signoz.cloud:443" \
|
OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.{region}.signoz.cloud:443" \
|
||||||
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=SIGNOZ_INGESTION_KEY" \
|
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=<SIGNOZ_INGESTION_KEY>" \
|
||||||
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
|
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
|
||||||
opentelemetry-instrument <your_run_command>
|
opentelemetry-instrument <your_run_command>
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<service_name>` is the name of the service you want
|
- `<service_name>` is the name of the service you want
|
||||||
- <your_run_command> can be `python3 app.py` or `python manage.py runserver --noreload`
|
- <your_run_command> can be `python3 app.py` or `python manage.py runserver --noreload`
|
||||||
- Replace `SIGNOZ_INGESTION_KEY` with the api token provided by SigNoz. You can find it in the email sent by SigNoz with your cloud account details.
|
- Replace `<SIGNOZ_INGESTION_KEY>` with the api token provided by SigNoz. You can find it in the email sent by SigNoz with your cloud account details.
|
||||||
|
|
||||||
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
||||||
|
|
||||||
US - ingest.us.signoz.cloud:443 <br></br>
|
US - ingest.us.signoz.cloud:443
|
||||||
|
|
||||||
IN - ingest.in.signoz.cloud:443 <br></br>
|
IN - ingest.in.signoz.cloud:443
|
||||||
|
|
||||||
EU - ingest.eu.signoz.cloud:443 <br></br>
|
EU - ingest.eu.signoz.cloud:443
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
Don’t run app in reloader/hot-reload mode as it breaks instrumentation. For example, you can disable the auto reload with `--noreload`.
|
Don’t run app in reloader/hot-reload mode as it breaks instrumentation. For example, you can disable the auto reload with `--noreload`.
|
||||||
@ -96,7 +80,7 @@ OTel Collector binary helps to collect logs, hostmetrics, resource and infra att
|
|||||||
|
|
||||||
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Python application.
|
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Python application.
|
||||||
|
|
||||||
Step 1. Create a virtual environment<br></br>
|
Step 1. Create a virtual environment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
@ -116,7 +100,7 @@ Step 3. Add automatic instrumentation
|
|||||||
opentelemetry-bootstrap --action=install
|
opentelemetry-bootstrap --action=install
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 4. To run your application and send data to collector in same VM:
|
Step 4. To run your application and send data to collector in same VM
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
@ -142,7 +126,7 @@ For Python application deployed on Kubernetes, you need to install OTel Collecto
|
|||||||
|
|
||||||
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Python instrumentation by following the below steps:
|
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Python instrumentation by following the below steps:
|
||||||
|
|
||||||
Step 1. Create a virtual environment<br></br>
|
Step 1. Create a virtual environment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
|
@ -10,12 +10,12 @@ Based on your application environment, you can choose the setup below to send tr
|
|||||||
|
|
||||||
From VMs, there are two ways to send data to SigNoz Cloud.
|
From VMs, there are two ways to send data to SigNoz Cloud.
|
||||||
|
|
||||||
- [Send traces directly to SigNoz Cloud](#send-traces-directly-to-signoz-cloud)
|
- Send traces directly to SigNoz Cloud (quick start)
|
||||||
- [Send traces via OTel Collector binary](#send-traces-via-otel-collector-binary) (recommended)
|
- Send traces via OTel Collector binary (recommended)
|
||||||
|
|
||||||
#### **Send traces directly to SigNoz Cloud**
|
#### **Send traces directly to SigNoz Cloud**
|
||||||
|
|
||||||
Step 1. Create a virtual environment<br></br>
|
Step 1. Create a virtual environment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
@ -29,23 +29,6 @@ pip install opentelemetry-distro==0.38b0
|
|||||||
pip install opentelemetry-exporter-otlp==1.17.0
|
pip install opentelemetry-exporter-otlp==1.17.0
|
||||||
```
|
```
|
||||||
|
|
||||||
<!-- The dependencies included are briefly explained below:
|
|
||||||
|
|
||||||
`opentelemetry-distro` - The distro provides a mechanism to automatically configure some of the more common options for users. It helps to get started with OpenTelemetry auto-instrumentation quickly.
|
|
||||||
|
|
||||||
`opentelemetry-exporter-otlp` - This library provides a way to install all OTLP exporters. You will need an exporter to send the data to SigNoz.
|
|
||||||
|
|
||||||
:::note
|
|
||||||
💡 The `opentelemetry-exporter-otlp` is a convenience wrapper package to install all OTLP exporters. Currently, it installs:
|
|
||||||
|
|
||||||
- opentelemetry-exporter-otlp-proto-http
|
|
||||||
- opentelemetry-exporter-otlp-proto-grpc
|
|
||||||
|
|
||||||
- (soon) opentelemetry-exporter-otlp-json-http
|
|
||||||
|
|
||||||
The `opentelemetry-exporter-otlp-proto-grpc` package installs the gRPC exporter which depends on the `grpcio` package. The installation of `grpcio` may fail on some platforms for various reasons. If you run into such issues, or you don't want to use gRPC, you can install the HTTP exporter instead by installing the `opentelemetry-exporter-otlp-proto-http` package. You need to set the `OTEL_EXPORTER_OTLP_PROTOCOL` environment variable to `http/protobuf` to use the HTTP exporter.
|
|
||||||
::: -->
|
|
||||||
|
|
||||||
Step 3. Add automatic instrumentation
|
Step 3. Add automatic instrumentation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -59,22 +42,22 @@ Step 4. Run your application
|
|||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.{region}.signoz.cloud:443" \
|
OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.{region}.signoz.cloud:443" \
|
||||||
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=SIGNOZ_INGESTION_KEY" \
|
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=<SIGNOZ_INGESTION_KEY>" \
|
||||||
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
|
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
|
||||||
opentelemetry-instrument <your_run_command>
|
opentelemetry-instrument <your_run_command>
|
||||||
```
|
```
|
||||||
|
|
||||||
- *`<service_name>`* is the name of the service you want
|
- *`<service_name>`* is the name of the service you want
|
||||||
- *<your_run_command>* can be `python3 app.py` or `flask run`
|
- *<your_run_command>* can be `python3 app.py` or `gunicorn src.app -b 0.0.0.0:8001`
|
||||||
- Replace `SIGNOZ_INGESTION_KEY` with the api token provided by SigNoz. You can find it in the email sent by SigNoz with your cloud account details.
|
- Replace `<SIGNOZ_INGESTION_KEY>` with the api token provided by SigNoz. You can find it in the email sent by SigNoz with your cloud account details.
|
||||||
|
|
||||||
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
||||||
|
|
||||||
US - ingest.us.signoz.cloud:443 <br></br>
|
US - ingest.us.signoz.cloud:443
|
||||||
|
|
||||||
IN - ingest.in.signoz.cloud:443 <br></br>
|
IN - ingest.in.signoz.cloud:443
|
||||||
|
|
||||||
EU - ingest.eu.signoz.cloud:443 <br></br>
|
EU - ingest.eu.signoz.cloud:443
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
Don’t run app in reloader/hot-reload mode as it breaks instrumentation. For example, you can disable the auto reload with `--noreload`.
|
Don’t run app in reloader/hot-reload mode as it breaks instrumentation. For example, you can disable the auto reload with `--noreload`.
|
||||||
@ -87,7 +70,7 @@ OTel Collector binary helps to collect logs, hostmetrics, resource and infra att
|
|||||||
|
|
||||||
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Python application.
|
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Python application.
|
||||||
|
|
||||||
Step 1. Create a virtual environment<br></br>
|
Step 1. Create a virtual environment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
@ -108,7 +91,7 @@ opentelemetry-bootstrap --action=install
|
|||||||
```
|
```
|
||||||
Please make sure that you have installed all the dependencies of your application before running the above command. The command will not install instrumentation for the dependencies which are not installed.
|
Please make sure that you have installed all the dependencies of your application before running the above command. The command will not install instrumentation for the dependencies which are not installed.
|
||||||
|
|
||||||
Step 4. To run your application and send data to collector in same VM:
|
Step 4. To run your application and send data to collector in same VM
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
@ -138,7 +121,7 @@ For Python application deployed on Kubernetes, you need to install OTel Collecto
|
|||||||
|
|
||||||
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Python instrumentation by following the below steps:
|
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Python instrumentation by following the below steps:
|
||||||
|
|
||||||
Step 1. Create a virtual environment<br></br>
|
Step 1. Create a virtual environment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
@ -160,7 +143,7 @@ opentelemetry-bootstrap --action=install
|
|||||||
|
|
||||||
Please make sure that you have installed all the dependencies of your application before running the above command. The command will not install instrumentation for the dependencies which are not installed.
|
Please make sure that you have installed all the dependencies of your application before running the above command. The command will not install instrumentation for the dependencies which are not installed.
|
||||||
|
|
||||||
Step 4. Run your application:
|
Step 4. Run your application
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
|
@ -10,12 +10,12 @@ Based on your application environment, you can choose the setup below to send tr
|
|||||||
|
|
||||||
From VMs, there are two ways to send data to SigNoz Cloud.
|
From VMs, there are two ways to send data to SigNoz Cloud.
|
||||||
|
|
||||||
- [Send traces directly to SigNoz Cloud](#send-traces-directly-to-signoz-cloud)
|
- Send traces directly to SigNoz Cloud (quick start)
|
||||||
- [Send traces via OTel Collector binary](#send-traces-via-otel-collector-binary) (recommended)
|
- Send traces via OTel Collector binary (recommended)
|
||||||
|
|
||||||
#### **Send traces directly to SigNoz Cloud**
|
#### **Send traces directly to SigNoz Cloud**
|
||||||
|
|
||||||
Step 1. Create a virtual environment<br></br>
|
Step 1. Create a virtual environment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
@ -42,22 +42,22 @@ Step 4. Run your application
|
|||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.{region}.signoz.cloud:443" \
|
OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.{region}.signoz.cloud:443" \
|
||||||
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=SIGNOZ_INGESTION_KEY" \
|
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=<SIGNOZ_INGESTION_KEY>" \
|
||||||
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
|
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
|
||||||
opentelemetry-instrument <your_run_command>
|
opentelemetry-instrument <your_run_command>
|
||||||
```
|
```
|
||||||
|
|
||||||
- *`<service_name>`* is the name of the service you want
|
- *`<service_name>`* is the name of the service you want
|
||||||
- *<your_run_command>* can be `python3 app.py` or `python manage.py runserver --noreload`
|
- *<your_run_command>* can be `python3 app.py` or `uvicorn main:app --host localhost --port 5002`
|
||||||
- Replace `SIGNOZ_INGESTION_KEY` with the api token provided by SigNoz. You can find it in the email sent by SigNoz with your cloud account details.
|
- Replace `<SIGNOZ_INGESTION_KEY>` with the api token provided by SigNoz. You can find it in the email sent by SigNoz with your cloud account details.
|
||||||
|
|
||||||
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
||||||
|
|
||||||
US - ingest.us.signoz.cloud:443 <br></br>
|
US - ingest.us.signoz.cloud:443
|
||||||
|
|
||||||
IN - ingest.in.signoz.cloud:443 <br></br>
|
IN - ingest.in.signoz.cloud:443
|
||||||
|
|
||||||
EU - ingest.eu.signoz.cloud:443 <br></br>
|
EU - ingest.eu.signoz.cloud:443
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
Don’t run app in reloader/hot-reload mode as it breaks instrumentation. For example, you can disable the auto reload with `--noreload`.
|
Don’t run app in reloader/hot-reload mode as it breaks instrumentation. For example, you can disable the auto reload with `--noreload`.
|
||||||
@ -70,7 +70,7 @@ OTel Collector binary helps to collect logs, hostmetrics, resource and infra att
|
|||||||
|
|
||||||
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Python application.
|
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Python application.
|
||||||
|
|
||||||
Step 1. Create a virtual environment<br></br>
|
Step 1. Create a virtual environment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
@ -92,7 +92,7 @@ opentelemetry-bootstrap --action=install
|
|||||||
|
|
||||||
Please make sure that you have installed all the dependencies of your application before running the above command. The command will not install instrumentation for the dependencies which are not installed.
|
Please make sure that you have installed all the dependencies of your application before running the above command. The command will not install instrumentation for the dependencies which are not installed.
|
||||||
|
|
||||||
Step 4. To run your application and send data to collector in same VM:
|
Step 4. To run your application and send data to collector in same VM
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
@ -119,7 +119,7 @@ For Python application deployed on Kubernetes, you need to install OTel Collecto
|
|||||||
|
|
||||||
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Python instrumentation by following the below steps:
|
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Python instrumentation by following the below steps:
|
||||||
|
|
||||||
Step 1. Create a virtual environment<br></br>
|
Step 1. Create a virtual environment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
@ -141,7 +141,7 @@ opentelemetry-bootstrap --action=install
|
|||||||
|
|
||||||
Please make sure that you have installed all the dependencies of your application before running the above command. The command will not install instrumentation for the dependencies which are not installed.
|
Please make sure that you have installed all the dependencies of your application before running the above command. The command will not install instrumentation for the dependencies which are not installed.
|
||||||
|
|
||||||
Step 4. Run your application:
|
Step 4. Run your application
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
|
@ -10,12 +10,12 @@ Based on your application environment, you can choose the setup below to send tr
|
|||||||
|
|
||||||
From VMs, there are two ways to send data to SigNoz Cloud.
|
From VMs, there are two ways to send data to SigNoz Cloud.
|
||||||
|
|
||||||
- [Send traces directly to SigNoz Cloud](#send-traces-directly-to-signoz-cloud)
|
- Send traces directly to SigNoz Cloud (quick start)
|
||||||
- [Send traces via OTel Collector binary](#send-traces-via-otel-collector-binary) (recommended)
|
- Send traces via OTel Collector binary (recommended)
|
||||||
|
|
||||||
#### **Send traces directly to SigNoz Cloud**
|
#### **Send traces directly to SigNoz Cloud**
|
||||||
|
|
||||||
Step 1. Create a virtual environment<br></br>
|
Step 1. Create a virtual environment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
@ -42,22 +42,22 @@ Step 4. Run your application
|
|||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.{region}.signoz.cloud:443" \
|
OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.{region}.signoz.cloud:443" \
|
||||||
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=SIGNOZ_INGESTION_KEY" \
|
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=<SIGNOZ_INGESTION_KEY>" \
|
||||||
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
|
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
|
||||||
opentelemetry-instrument <your_run_command>
|
opentelemetry-instrument <your_run_command>
|
||||||
```
|
```
|
||||||
|
|
||||||
- *`<service_name>`* is the name of the service you want
|
- *`<service_name>`* is the name of the service you want
|
||||||
- *<your_run_command>* can be `python3 app.py` or `flask run`
|
- *<your_run_command>* can be `python3 app.py` or `flask run`
|
||||||
- Replace `SIGNOZ_INGESTION_KEY` with the api token provided by SigNoz. You can find it in the email sent by SigNoz with your cloud account details.
|
- Replace `<SIGNOZ_INGESTION_KEY>` with the api token provided by SigNoz. You can find it in the email sent by SigNoz with your cloud account details.
|
||||||
|
|
||||||
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
||||||
|
|
||||||
US - ingest.us.signoz.cloud:443 <br></br>
|
US - ingest.us.signoz.cloud:443
|
||||||
|
|
||||||
IN - ingest.in.signoz.cloud:443 <br></br>
|
IN - ingest.in.signoz.cloud:443
|
||||||
|
|
||||||
EU - ingest.eu.signoz.cloud:443 <br></br>
|
EU - ingest.eu.signoz.cloud:443
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
Don’t run app in reloader/hot-reload mode as it breaks instrumentation. For example, you can disable the auto reload with `--noreload`.
|
Don’t run app in reloader/hot-reload mode as it breaks instrumentation. For example, you can disable the auto reload with `--noreload`.
|
||||||
@ -70,7 +70,7 @@ OTel Collector binary helps to collect logs, hostmetrics, resource and infra att
|
|||||||
|
|
||||||
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Python application.
|
You can find instructions to install OTel Collector binary [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/) in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Python application.
|
||||||
|
|
||||||
Step 1. Create a virtual environment<br></br>
|
Step 1. Create a virtual environment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
@ -92,7 +92,7 @@ opentelemetry-bootstrap --action=install
|
|||||||
|
|
||||||
Please make sure that you have installed all the dependencies of your application before running the above command. The command will not install instrumentation for the dependencies which are not installed.
|
Please make sure that you have installed all the dependencies of your application before running the above command. The command will not install instrumentation for the dependencies which are not installed.
|
||||||
|
|
||||||
Step 4. To run your application and send data to collector in same VM:
|
Step 4. To run your application and send data to collector in same VM
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
@ -121,7 +121,7 @@ For Python application deployed on Kubernetes, you need to install OTel Collecto
|
|||||||
|
|
||||||
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Python instrumentation by following the below steps:
|
Once you have set up OTel Collector agent, you can proceed with OpenTelemetry Python instrumentation by following the below steps:
|
||||||
|
|
||||||
Step 1. Create a virtual environment<br></br>
|
Step 1. Create a virtual environment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
@ -144,7 +144,7 @@ opentelemetry-bootstrap --action=install
|
|||||||
|
|
||||||
Please make sure that you have installed all the dependencies of your application before running the above command. The command will not install instrumentation for the dependencies which are not installed.
|
Please make sure that you have installed all the dependencies of your application before running the above command. The command will not install instrumentation for the dependencies which are not installed.
|
||||||
|
|
||||||
Step 4. Run your application:
|
Step 4. Run your application
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
|
@ -10,8 +10,8 @@ Based on your application environment, you can choose the setup below to send tr
|
|||||||
|
|
||||||
From VMs, there are two ways to send data to SigNoz Cloud.
|
From VMs, there are two ways to send data to SigNoz Cloud.
|
||||||
|
|
||||||
- [Send traces directly to SigNoz Cloud](#send-traces-directly-to-signoz-cloud)
|
- Send traces directly to SigNoz Cloud (quick start)
|
||||||
- [Send traces via OTel Collector binary](#send-traces-via-otel-collector-binary) (recommended)
|
- Send traces via OTel Collector binary (recommended)
|
||||||
|
|
||||||
#### **Send traces directly to SigNoz Cloud**
|
#### **Send traces directly to SigNoz Cloud**
|
||||||
|
|
||||||
@ -33,21 +33,21 @@ Step 3. Run your application
|
|||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.{region}.signoz.cloud:443" \
|
OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.{region}.signoz.cloud:443" \
|
||||||
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=SIGNOZ_INGESTION_KEY" \
|
OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=<SIGNOZ_INGESTION_KEY>" \
|
||||||
opentelemetry-instrument <your_run_command>
|
opentelemetry-instrument <your_run_command>
|
||||||
```
|
```
|
||||||
|
|
||||||
- *`<service_name>`* is the name of the service you want
|
- *`<service_name>`* is the name of the service you want
|
||||||
- *`<your_run_command>`* can be `python3 app.py` or `flask run`
|
- *`<your_run_command>`* can be `python3 app.py` or `flask run`
|
||||||
- Replace `SIGNOZ_INGESTION_KEY` with the api token provided by SigNoz. You can find it in the email sent by SigNoz with your cloud account details.
|
- Replace `<SIGNOZ_INGESTION_KEY>` with the api token provided by SigNoz. You can find it in the email sent by SigNoz with your cloud account details.
|
||||||
|
|
||||||
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
||||||
|
|
||||||
US - ingest.us.signoz.cloud:443 <br></br>
|
US - ingest.us.signoz.cloud:443
|
||||||
|
|
||||||
IN - ingest.in.signoz.cloud:443 <br></br>
|
IN - ingest.in.signoz.cloud:443
|
||||||
|
|
||||||
EU - ingest.eu.signoz.cloud:443 <br></br>
|
EU - ingest.eu.signoz.cloud:443
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
Don’t run app in reloader/hot-reload mode as it breaks instrumentation.
|
Don’t run app in reloader/hot-reload mode as it breaks instrumentation.
|
||||||
@ -73,7 +73,7 @@ Step 2. Add automatic instrumentation
|
|||||||
opentelemetry-bootstrap --action=install
|
opentelemetry-bootstrap --action=install
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 3. To run your application and send data to collector in same VM:
|
Step 3. To run your application and send data to collector in same VM
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
@ -118,7 +118,7 @@ Step 2. Add automatic instrumentation
|
|||||||
opentelemetry-bootstrap --action=install
|
opentelemetry-bootstrap --action=install
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 3. Run your application:
|
Step 3. Run your application
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
OTEL_RESOURCE_ATTRIBUTES=service.name=<service_name> \
|
||||||
|
@ -1,6 +1,18 @@
|
|||||||
.infrastructure-monitoring-module-container {
|
.infrastructure-monitoring-module-container {
|
||||||
padding: 48px 0;
|
padding: 48px 0;
|
||||||
|
|
||||||
|
.module-header {
|
||||||
|
h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.content-container {
|
.content-container {
|
||||||
.heading {
|
.heading {
|
||||||
.title {
|
.title {
|
||||||
@ -21,15 +33,13 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
h1 {
|
.header {
|
||||||
font-size: 24px;
|
display: flex;
|
||||||
font-weight: 500;
|
gap: 16px;
|
||||||
}
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
h4 {
|
margin: 16px 0;
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,39 +1,154 @@
|
|||||||
|
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||||
|
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
||||||
import './InfrastructureMonitoring.styles.scss';
|
import './InfrastructureMonitoring.styles.scss';
|
||||||
|
|
||||||
import { MDXProvider } from '@mdx-js/react';
|
import cx from 'classnames';
|
||||||
|
import { Code, Pre } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
import { trackEvent } from 'utils/segmentAnalytics';
|
||||||
|
|
||||||
import InfraMonitoringDocs from './infraMonitoringDocs.md';
|
import Header from '../common/Header/Header';
|
||||||
|
import hostMetricsMonitoring from './md-docs/hostMetricsMonitoring.md';
|
||||||
|
import k8sInfraMonitoringDocs from './md-docs/kubernetesInfraMonitoring.md';
|
||||||
|
import otherMetrics from './md-docs/otherMetrics.md';
|
||||||
|
|
||||||
export default function InfrastructureMonitoring({
|
export default function InfrastructureMonitoring({
|
||||||
activeStep,
|
activeStep,
|
||||||
}: {
|
}: {
|
||||||
activeStep: number;
|
activeStep: number;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const docsURL = 'https://signoz.io/docs/userguide/send-metrics-cloud/';
|
const [selectedInfraMetrics, setSelectedInfraMetrics] = useState('kubernetes');
|
||||||
const heading = 'Send Metrics to SigNoz Cloud';
|
const [selectedInfraMetricsDocs, setSelectedInfraMetricsDocs] = useState(
|
||||||
|
k8sInfraMonitoringDocs,
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// on metrics Type select
|
||||||
|
trackEvent('Onboarding: APM : Java', {
|
||||||
|
selectedInfraMetrics,
|
||||||
|
});
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [selectedInfraMetrics]);
|
||||||
|
|
||||||
|
const supportedInfraMetrics = [
|
||||||
|
{
|
||||||
|
name: 'Kubernetes Infra Metrics',
|
||||||
|
id: 'kubernetes',
|
||||||
|
imgURL: `Logos/kubernetes.svg`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'HostMetrics',
|
||||||
|
id: 'hostMetrics',
|
||||||
|
imgURL: `Logos/software-window.svg`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Other Metrics',
|
||||||
|
id: 'otherMetrics',
|
||||||
|
imgURL: `Logos/cmd-terminal.svg`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleMetricsTypeChange = (selectedMetricsType: string): void => {
|
||||||
|
setSelectedInfraMetrics(selectedMetricsType);
|
||||||
|
|
||||||
|
switch (selectedMetricsType) {
|
||||||
|
case 'kubernetes':
|
||||||
|
setSelectedInfraMetricsDocs(k8sInfraMonitoringDocs);
|
||||||
|
break;
|
||||||
|
case 'hostMetrics':
|
||||||
|
setSelectedInfraMetricsDocs(hostMetricsMonitoring);
|
||||||
|
break;
|
||||||
|
case 'otherMetrics':
|
||||||
|
setSelectedInfraMetricsDocs(otherMetrics);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
setSelectedInfraMetricsDocs(otherMetrics);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getHeaderBasedOnType = (): JSX.Element => {
|
||||||
|
switch (selectedInfraMetrics) {
|
||||||
|
case 'hostMetrics':
|
||||||
|
return (
|
||||||
|
<Header
|
||||||
|
entity="hostMetrics"
|
||||||
|
heading="Host Metrics"
|
||||||
|
imgURL="/Logos/software-window.svg"
|
||||||
|
docsURL="https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/"
|
||||||
|
imgClassName="supported-logs-type-img"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case 'otherMetrics':
|
||||||
|
return (
|
||||||
|
<Header
|
||||||
|
entity="otherMetrics"
|
||||||
|
heading="Other Metrics"
|
||||||
|
imgURL="/Logos/cmd-terminal.svg"
|
||||||
|
docsURL="https://signoz.io/docs/userguide/send-metrics-cloud/"
|
||||||
|
imgClassName="supported-logs-type-img"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (
|
||||||
|
<Header
|
||||||
|
entity="kubernetes"
|
||||||
|
heading="Kubernetes Metrics"
|
||||||
|
imgURL="/Logos/kubernetes.svg"
|
||||||
|
docsURL="https://signoz.io/docs/tutorial/kubernetes-infra-metrics/"
|
||||||
|
imgClassName="supported-logs-type-img"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="infrastructure-monitoring-module-container">
|
<div className="infrastructure-monitoring-module-container">
|
||||||
{activeStep === 2 && (
|
{activeStep === 2 && (
|
||||||
<div className="content-container">
|
<>
|
||||||
<div className="header">
|
<div className="module-header">
|
||||||
<div className="title">
|
<h1>Select an Infra Metrics type</h1>
|
||||||
<h1>{heading}</h1>
|
{/* <h4> Choose the logs that you want to receive on SigNoz </h4> */}
|
||||||
|
|
||||||
<div className="detailed-docs-link">
|
|
||||||
View detailed docs
|
|
||||||
<a target="_blank" href={docsURL} rel="noreferrer">
|
|
||||||
here
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MDXProvider>
|
<div className="supported-logs-type-container">
|
||||||
<InfraMonitoringDocs />
|
{supportedInfraMetrics.map((logType) => (
|
||||||
</MDXProvider>
|
<div
|
||||||
</div>
|
className={cx(
|
||||||
|
'supported-logs-type',
|
||||||
|
selectedInfraMetrics === logType.id ? 'selected' : '',
|
||||||
|
)}
|
||||||
|
key={logType.name}
|
||||||
|
onClick={(): void => handleMetricsTypeChange(logType.id)}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
className={cx('supported-logs-type-img')}
|
||||||
|
src={`${logType.imgURL}`}
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div> {logType.name} </div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{getHeaderBasedOnType()}
|
||||||
|
|
||||||
|
<div className="content-container">
|
||||||
|
<ReactMarkdown
|
||||||
|
components={{
|
||||||
|
pre: Pre,
|
||||||
|
code: Code,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{selectedInfraMetricsDocs}
|
||||||
|
</ReactMarkdown>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{activeStep === 3 && <div> Infra Monitoring Step 3 </div>}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
## Hostmetrics Monitoring
|
||||||
|
You can collect Hostmetrics from your VM and send it to SigNoz cloud using OpenTelemetry Collector.
|
||||||
|
|
||||||
|
Steps to send hostmetrics to SigNoz Cloud:
|
||||||
|
|
||||||
|
- Install OpenTelemetry Collector binary agent. Please find instructions [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/#setup-otel-collector-as-agent).
|
||||||
|
|
||||||
|
- Import Hostmetrics Dashboard in SigNoz. Please find instructions [here](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/#hostmetrics-dashboard).
|
||||||
|
|
||||||
|
Learn how to create dashboards and panels [here](https://signoz.io/docs/userguide/manage-dashboards-and-panels/).
|
@ -0,0 +1,9 @@
|
|||||||
|
## Kubernetes Infra Metrics
|
||||||
|
|
||||||
|
You can collect Kubernetes infra metrics from your k8s cluster and send it to SigNoz cloud using k8s-infra chart.
|
||||||
|
|
||||||
|
Steps to send kubernetes infra metrics to SigNoz Cloud:
|
||||||
|
|
||||||
|
- Install OpenTelemetry Collectors in your k8s infra. Please find instructions [here](https://signoz.io/docs/tutorial/kubernetes-infra-metrics/).
|
||||||
|
|
||||||
|
- Plot metrics in SigNoz UI by following the instructions [here](https://signoz.io/docs/tutorial/kubernetes-infra-metrics/#plot-metrics-in-signoz-ui).
|
@ -1,3 +1,7 @@
|
|||||||
|
## Send metrics from any third-party integrations
|
||||||
|
|
||||||
|
This document helps you to send metrics from any third-party integrations such as RabbitMQ, Nginx, MySQL, etc.
|
||||||
|
|
||||||
There are two ways in which you can send metrics to SigNoz using OpenTelemetry:
|
There are two ways in which you can send metrics to SigNoz using OpenTelemetry:
|
||||||
|
|
||||||
- From your application
|
- From your application
|
||||||
@ -5,8 +9,8 @@ There are two ways in which you can send metrics to SigNoz using OpenTelemetry:
|
|||||||
|
|
||||||
In this document, we will cover how to send metrics from OpenTelemetry Collector. The Collector is a swiss-army knife that can collect metrics from various sources and send them to SigNoz.
|
In this document, we will cover how to send metrics from OpenTelemetry Collector. The Collector is a swiss-army knife that can collect metrics from various sources and send them to SigNoz.
|
||||||
|
|
||||||
- [Enable a Specific Metric Receiver](#enable-a-specific-metric-receiver)
|
- Enable a Specific Metric Receiver
|
||||||
- [Enable a Prometheus Receiver](#enable-a-prometheus-receiver)
|
- Enable a Prometheus Receiver
|
||||||
|
|
||||||
## Enable a Specific Metric Receiver
|
## Enable a Specific Metric Receiver
|
||||||
|
|
||||||
@ -71,11 +75,11 @@ service:
|
|||||||
|
|
||||||
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
|
||||||
|
|
||||||
US - ingest.us.signoz.cloud:443 <br></br>
|
US - ingest.us.signoz.cloud:443
|
||||||
|
|
||||||
IN - ingest.in.signoz.cloud:443 <br></br>
|
IN - ingest.in.signoz.cloud:443
|
||||||
|
|
||||||
EU - ingest.eu.signoz.cloud:443 <br></br>
|
EU - ingest.eu.signoz.cloud:443
|
||||||
|
|
||||||
To enable a new OpenTelemetry receiver, follow the steps below:
|
To enable a new OpenTelemetry receiver, follow the steps below:
|
||||||
|
|
@ -1,11 +1,9 @@
|
|||||||
import { MDXProvider } from '@mdx-js/react';
|
import { Code, Pre } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||||
import { Tabs } from 'antd';
|
|
||||||
import Header from 'container/OnboardingContainer/common/Header/Header';
|
import Header from 'container/OnboardingContainer/common/Header/Header';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
|
||||||
import ConnectionStatus from '../common/LogsConnectionStatus/LogsConnectionStatus';
|
import ConnectionStatus from '../common/LogsConnectionStatus/LogsConnectionStatus';
|
||||||
import LogsFromLogFile from './applicationLogsFromLogFile.md';
|
import LogsFromLogFile from './applicationLogsFromLogFile.md';
|
||||||
import LogsUsingJavaOtelSDK from './applicationLogsUsingJavaOtelSDK.md';
|
|
||||||
import LogsUsingPythonOtelSDK from './applicationLogsUsingPythonOtelSDK.md';
|
|
||||||
|
|
||||||
interface ApplicationLogsProps {
|
interface ApplicationLogsProps {
|
||||||
type: string;
|
type: string;
|
||||||
@ -14,29 +12,12 @@ interface ApplicationLogsProps {
|
|||||||
|
|
||||||
const collectLogsFromFileURL =
|
const collectLogsFromFileURL =
|
||||||
'https://signoz.io/docs/userguide/collect_logs_from_file/';
|
'https://signoz.io/docs/userguide/collect_logs_from_file/';
|
||||||
const collectLogsFromOTELSDK =
|
|
||||||
'https://signoz.io/docs/userguide/collecting_application_logs_otel_sdk_java/';
|
|
||||||
|
|
||||||
export default function ApplicationLogs({
|
export default function ApplicationLogs({
|
||||||
type,
|
type,
|
||||||
activeStep,
|
activeStep,
|
||||||
}: ApplicationLogsProps): JSX.Element {
|
}: ApplicationLogsProps): JSX.Element {
|
||||||
function renderContentForCollectingLogsOtelSDK(language: string): JSX.Element {
|
const docsURL = collectLogsFromFileURL;
|
||||||
if (language === 'Java') {
|
|
||||||
return <LogsUsingJavaOtelSDK />;
|
|
||||||
}
|
|
||||||
return <LogsUsingPythonOtelSDK />;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ApplicationLogsType {
|
|
||||||
FROM_LOG_FILE = 'from-log-file',
|
|
||||||
USING_OTEL_COLLECTOR = 'using-otel-sdk',
|
|
||||||
}
|
|
||||||
|
|
||||||
const docsURL =
|
|
||||||
type === ApplicationLogsType.FROM_LOG_FILE
|
|
||||||
? collectLogsFromFileURL
|
|
||||||
: collectLogsFromOTELSDK;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -44,38 +25,21 @@ export default function ApplicationLogs({
|
|||||||
<div className="golang-setup-instructions-container">
|
<div className="golang-setup-instructions-container">
|
||||||
<Header
|
<Header
|
||||||
entity="docker"
|
entity="docker"
|
||||||
heading={
|
heading="Collecting Application Logs from Log file"
|
||||||
type === ApplicationLogsType.FROM_LOG_FILE
|
imgURL={`/Logos/${'software-window'}.svg`}
|
||||||
? 'Collecting Application Logs from Log file'
|
|
||||||
: 'Collecting Application Logs Using OTEL SDK'
|
|
||||||
}
|
|
||||||
imgURL={`/Logos/${
|
|
||||||
type === ApplicationLogsType.FROM_LOG_FILE
|
|
||||||
? 'software-window'
|
|
||||||
: 'cmd-terminal'
|
|
||||||
}.svg`}
|
|
||||||
docsURL={docsURL}
|
docsURL={docsURL}
|
||||||
imgClassName="supported-logs-type-img"
|
imgClassName="supported-logs-type-img"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="content-container">
|
<div className="content-container">
|
||||||
<MDXProvider>
|
<ReactMarkdown
|
||||||
{type === ApplicationLogsType.FROM_LOG_FILE && <LogsFromLogFile />}
|
components={{
|
||||||
{type === ApplicationLogsType.USING_OTEL_COLLECTOR && (
|
pre: Pre,
|
||||||
<Tabs
|
code: Code,
|
||||||
defaultActiveKey="1"
|
}}
|
||||||
items={['Java', 'Python'].map((language, i) => {
|
>
|
||||||
const id = String(i + 1);
|
{LogsFromLogFile}
|
||||||
|
</ReactMarkdown>
|
||||||
return {
|
|
||||||
label: <div className="language-tab-item">{language}</div>,
|
|
||||||
key: id,
|
|
||||||
children: renderContentForCollectingLogsOtelSDK(language),
|
|
||||||
};
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</MDXProvider>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
## Collect Application Logs from Log file in SigNoz cloud
|
## Collect Application Logs from Log file in SigNoz cloud
|
||||||
|
|
||||||
If you don’t already have a SigNoz cloud account, you can sign up [here](https://signoz.io/teams/).
|
|
||||||
|
|
||||||
- Add otel collector binary to your VM by following this [guide](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/).
|
- Add otel collector binary to your VM by following this [guide](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/).
|
||||||
|
|
||||||
- Add the filelog reciever to `config.yaml`.
|
- Add the filelog reciever to `config.yaml`.
|
||||||
@ -35,4 +33,5 @@ If you don’t already have a SigNoz cloud account, you can sign up [here](https
|
|||||||
- Now we can restart the otel collector so that new changes are applied.
|
- Now we can restart the otel collector so that new changes are applied.
|
||||||
|
|
||||||
- The log will be exported, if you add more lines to the log file it will be exported as well
|
- The log will be exported, if you add more lines to the log file it will be exported as well
|
||||||
|
|
||||||
- If there are no errors your logs will be visible on SigNoz UI.
|
- If there are no errors your logs will be visible on SigNoz UI.
|
||||||
|
@ -13,7 +13,7 @@ The command for it will look like
|
|||||||
OTEL_LOGS_EXPORTER=otlp OTEL_EXPORTER_OTLP_ENDPOINT="http://<IP of SigNoz Backend>:4317" OTEL_RESOURCE_ATTRIBUTES=service.name=<app_name> java -javaagent:/path/opentelemetry-javaagent.jar -jar <myapp>.jar
|
OTEL_LOGS_EXPORTER=otlp OTEL_EXPORTER_OTLP_ENDPOINT="http://<IP of SigNoz Backend>:4317" OTEL_RESOURCE_ATTRIBUTES=service.name=<app_name> java -javaagent:/path/opentelemetry-javaagent.jar -jar <myapp>.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
<br></br>
|
|
||||||
|
|
||||||
In the below example we will configure a java application to send logs to SigNoz.
|
In the below example we will configure a java application to send logs to SigNoz.
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { MDXProvider } from '@mdx-js/react';
|
import { Code, Pre } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||||
import Header from 'container/OnboardingContainer/common/Header/Header';
|
import Header from 'container/OnboardingContainer/common/Header/Header';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
|
||||||
import ConnectionStatus from '../common/LogsConnectionStatus/LogsConnectionStatus';
|
import ConnectionStatus from '../common/LogsConnectionStatus/LogsConnectionStatus';
|
||||||
import Post from './docker.md';
|
import DockerDocs from './docker.md';
|
||||||
|
|
||||||
export default function Docker({
|
export default function Docker({
|
||||||
activeStep,
|
activeStep,
|
||||||
@ -22,9 +23,14 @@ export default function Docker({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="content-container">
|
<div className="content-container">
|
||||||
<MDXProvider>
|
<ReactMarkdown
|
||||||
<Post />
|
components={{
|
||||||
</MDXProvider>
|
pre: Pre,
|
||||||
|
code: Code,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{DockerDocs}
|
||||||
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -1,70 +1,23 @@
|
|||||||
## Collect Syslogs in SigNoz cloud
|
## Collect Docker Container Logs in SigNoz Cloud
|
||||||
|
|
||||||
### Setup Otel Collector as agent
|
- Clone this [repository](https://github.com/SigNoz/docker-container-logs)
|
||||||
|
|
||||||
- Add `config.yaml`
|
- Update `otel-collector-config.yaml` and set the values of `<SIGNOZ_INGESTION_KEY>` and `{region}`.
|
||||||
```yaml {22-26}
|
|
||||||
receivers:
|
|
||||||
filelog:
|
|
||||||
include: [/tmp/python.log]
|
|
||||||
start_at: beginning
|
|
||||||
operators:
|
|
||||||
- type: json_parser
|
|
||||||
timestamp:
|
|
||||||
parse_from: attributes.time
|
|
||||||
layout: '%Y-%m-%d,%H:%M:%S %z'
|
|
||||||
- type: move
|
|
||||||
from: attributes.message
|
|
||||||
to: body
|
|
||||||
- type: remove
|
|
||||||
field: attributes.time
|
|
||||||
processors:
|
|
||||||
batch:
|
|
||||||
send_batch_size: 10000
|
|
||||||
send_batch_max_size: 11000
|
|
||||||
timeout: 10s
|
|
||||||
exporters:
|
|
||||||
otlp:
|
|
||||||
endpoint: 'ingest.{region}.signoz.cloud:443'
|
|
||||||
tls:
|
|
||||||
insecure: false
|
|
||||||
headers:
|
|
||||||
'signoz-access-token': '<SIGNOZ_INGESTION_KEY>'
|
|
||||||
service:
|
|
||||||
pipelines:
|
|
||||||
logs:
|
|
||||||
receivers: [filelog]
|
|
||||||
processors: [batch]
|
|
||||||
exporters: [otlp/log]
|
|
||||||
```
|
|
||||||
|
|
||||||
````
|
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary accordingly.
|
||||||
Depending on the choice of your region for SigNoz cloud, the otlp endpoint will vary according to this table.
|
|
||||||
|
|
||||||
| Region | Endpoint |
|
US - ingest.us.signoz.cloud:443
|
||||||
| ------ | -------------------------- |
|
|
||||||
| US | ingest.us.signoz.cloud:443 |
|
|
||||||
| IN | ingest.in.signoz.cloud:443 |
|
|
||||||
| EU | ingest.eu.signoz.cloud:443 |
|
|
||||||
|
|
||||||
* We will start our otel-collector container.
|
IN - ingest.in.signoz.cloud:443
|
||||||
```bash
|
|
||||||
docker run -d --name signoz-host-otel-collector -p 2255:2255 --user root -v $(pwd)/config.yaml:/etc/otel/config.yaml signoz/signoz-otel-collector:0.79.0
|
|
||||||
````
|
|
||||||
|
|
||||||
### Run logspout to collect docker container logs and send it to local otel collector.
|
EU - ingest.eu.signoz.cloud:443
|
||||||
|
|
||||||
Logspout helps in collecting Docker logs by connecting to Docker socket.
|
|
||||||
|
|
||||||
- Run logspout
|
- Start the containers
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
```bash
|
- If there are no errors your logs will be exported and will be visible on the SigNoz UI.
|
||||||
docker run --net=host --rm --name="logspout" \
|
|
||||||
--volume=/var/run/docker.sock:/var/run/docker.sock \
|
|
||||||
gliderlabs/logspout \
|
|
||||||
syslog+tcp://<host>:2255
|
|
||||||
```
|
|
||||||
|
|
||||||
For finding the right host for your SigNoz cluster please follow the guide [here](../install/troubleshooting.md#signoz-otel-collector-address-grid).
|
|
||||||
|
|
||||||
- If there are no errors your logs will be exported and will be visible on the SigNoz UI.
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { MDXProvider } from '@mdx-js/react';
|
|
||||||
import { Select } from 'antd';
|
import { Select } from 'antd';
|
||||||
|
import { Code, Pre } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||||
import Header from 'container/OnboardingContainer/common/Header/Header';
|
import Header from 'container/OnboardingContainer/common/Header/Header';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
import { trackEvent } from 'utils/segmentAnalytics';
|
import { trackEvent } from 'utils/segmentAnalytics';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import FluentBit from './md-docs/fluentBit.md';
|
import FluentBit from './md-docs/fluentBit.md';
|
||||||
import FluentD from './md-docs/fluentD.md';
|
import FluentD from './md-docs/fluentD.md';
|
||||||
@ -16,6 +18,7 @@ enum FrameworksMap {
|
|||||||
|
|
||||||
export default function ExistingCollectors(): JSX.Element {
|
export default function ExistingCollectors(): JSX.Element {
|
||||||
const [selectedFrameWork, setSelectedFrameWork] = useState('fluent_d');
|
const [selectedFrameWork, setSelectedFrameWork] = useState('fluent_d');
|
||||||
|
const [selectedFrameWorkDocs, setSelectedFrameWorkDocs] = useState(FluentD);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// on language select
|
// on language select
|
||||||
@ -25,14 +28,19 @@ export default function ExistingCollectors(): JSX.Element {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [selectedFrameWork]);
|
}, [selectedFrameWork]);
|
||||||
|
|
||||||
const renderDocs = (): JSX.Element => {
|
const handleFrameworkChange = (selectedFrameWork: string): void => {
|
||||||
|
setSelectedFrameWork(selectedFrameWork);
|
||||||
|
|
||||||
switch (selectedFrameWork) {
|
switch (selectedFrameWork) {
|
||||||
case 'fluent_d':
|
case 'fluent_d':
|
||||||
return <FluentD />;
|
setSelectedFrameWorkDocs(FluentD);
|
||||||
|
break;
|
||||||
case 'fluent_bit':
|
case 'fluent_bit':
|
||||||
return <FluentBit />;
|
setSelectedFrameWorkDocs(FluentBit);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return <LogStashDocs />;
|
setSelectedFrameWorkDocs(LogStashDocs);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,10 +59,11 @@ export default function ExistingCollectors(): JSX.Element {
|
|||||||
<div className="label"> Select Framework </div>
|
<div className="label"> Select Framework </div>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
defaultValue="fluent_d"
|
defaultValue="fluent_d"
|
||||||
style={{ minWidth: 120 }}
|
style={{ minWidth: 120 }}
|
||||||
placeholder="Select Framework"
|
placeholder="Select Framework"
|
||||||
onChange={(value): void => setSelectedFrameWork(value)}
|
onChange={(value): void => handleFrameworkChange(value)}
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
value: 'fluent_d',
|
value: 'fluent_d',
|
||||||
@ -74,7 +83,14 @@ export default function ExistingCollectors(): JSX.Element {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="content-container">
|
<div className="content-container">
|
||||||
<MDXProvider>{renderDocs()}</MDXProvider>
|
<ReactMarkdown
|
||||||
|
components={{
|
||||||
|
pre: Pre,
|
||||||
|
code: Code,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{selectedFrameWorkDocs}
|
||||||
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,66 +1,58 @@
|
|||||||
If you use fluentBit to collect logs in your stack with this tutotrial you will be able to send logs from fluentBit to SigNoz.
|
## Collect Logs Using FluentBit in SigNoz cloud
|
||||||
|
|
||||||
|
If you use fluentBit to collect logs in your stack, you will be able to send logs from fluentBit to SigNoz.
|
||||||
|
|
||||||
At SigNoz we use opentelemetry collector to recieve logs which supports the fluentforward protocol. So you can forward your logs from your fluentBit agent to opentelemetry collector using fluentforward protocol.
|
At SigNoz we use opentelemetry collector to recieve logs which supports the fluentforward protocol. So you can forward your logs from your fluentBit agent to opentelemetry collector using fluentforward protocol.
|
||||||
|
|
||||||
### Collect Logs Using FluentBit in SigNoz cloud
|
* Add otel collector binary to your VM by following this [guide](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/).
|
||||||
|
|
||||||
- Add otel collector binary to your VM by following this [guide](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/).
|
* Add fluentforward reciever to your `config.yaml`
|
||||||
- Add fluentforward reciever to your `config.yaml`
|
```yaml
|
||||||
|
receivers:
|
||||||
|
fluentforward:
|
||||||
|
endpoint: 0.0.0.0:24224
|
||||||
|
```
|
||||||
|
Here we have used port 24224 for listening in fluentforward protocol, but you can change it to a port you want.
|
||||||
|
You can read more about fluentforward receiver [here](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/fluentforwardreceiver).
|
||||||
|
|
||||||
```yaml
|
* Modify your `config.yaml` and add the above receiver
|
||||||
receivers:
|
```yaml {4}
|
||||||
fluentforward:
|
service:
|
||||||
endpoint: 0.0.0.0:24224
|
....
|
||||||
```
|
logs:
|
||||||
|
receivers: [otlp, fluentforward]
|
||||||
|
processors: [batch]
|
||||||
|
exporters: [otlp]
|
||||||
|
```
|
||||||
|
|
||||||
Here we have used port 24224 for listing in fluentforward protocol, but you can change it to a port you want.
|
* Add the following to your fluentBit config to forward the logs to otel collector.
|
||||||
You can read more about fluentforward receiver [here](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/fluentforwardreceiver).
|
```
|
||||||
|
[OUTPUT]
|
||||||
|
Name forward
|
||||||
|
Match *
|
||||||
|
Host localhost
|
||||||
|
Port 24224
|
||||||
|
```
|
||||||
|
In this config we are forwarding the logs to the otel collector which is listening on port 24224.
|
||||||
|
Also we are assuming that you are running the fluentBit binary on the host. If not, the value of `host` might change depending on your environment.
|
||||||
|
|
||||||
- Modify your `config.yaml` and add the above receiver
|
* Once you make this changes you can restart fluentBit and otel-binary, and you will be able to see the logs in SigNoz.
|
||||||
```yaml {4}
|
|
||||||
service:
|
|
||||||
....
|
|
||||||
logs:
|
|
||||||
receivers: [otlp, fluentforward]
|
|
||||||
processors: [batch]
|
|
||||||
exporters: [otlp]
|
|
||||||
```
|
|
||||||
- Change the fluentBit config to forward the logs to otel collector.
|
|
||||||
|
|
||||||
```
|
* To properly transform your existing log model into opentelemetry [log](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md) model you can use the different processors provided by opentelemetry. ([link](https://signoz.io/docs/userguide/logs/#processors-available-for-processing-logs))
|
||||||
[INPUT]
|
|
||||||
Name dummy
|
eg:-
|
||||||
Tag dummy.log
|
```yaml
|
||||||
Dummy {"message": "mylog", "trace_id": "0000000000000000f4dbb3edd765f620", "span_id": "43222c2d51a7abe3"}
|
processors:
|
||||||
|
logstransform:
|
||||||
[OUTPUT]
|
operators:
|
||||||
Name forward
|
- type: trace_parser
|
||||||
Match *
|
trace_id:
|
||||||
Host otel-collector-host
|
parse_from: attributes.trace_id
|
||||||
Port 24224
|
span_id:
|
||||||
```
|
parse_from: attributes.span_id
|
||||||
|
- type: remove
|
||||||
In this example we are generating sample logs and then forwarding them to the otel collector which is listening on port 24224.
|
field: attributes.trace_id
|
||||||
`otel-collector-host` has to be replaced by the host where otel-collector is running. For more info check [troubleshooting](../install/troubleshooting.md#signoz-otel-collector-address-grid).
|
- type: remove
|
||||||
|
field: attributes.span_id
|
||||||
- Once you make this changes you can restart fluentBit and otel-binary, and you will be able to see the logs in SigNoz.
|
```
|
||||||
- To properly transform your existing log model into opentelemetry [log](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md) model you can use the different processors provided by opentelemetry. [link](./logs.md#processors-available-for-processing-logs)
|
The operations in the above processor will parse the trace_id and span_id from log to opentelemetry log model and remove them from attributes.
|
||||||
|
|
||||||
eg:-
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
processors:
|
|
||||||
logstransform:
|
|
||||||
operators:
|
|
||||||
- type: trace_parser
|
|
||||||
trace_id:
|
|
||||||
parse_from: attributes.trace_id
|
|
||||||
span_id:
|
|
||||||
parse_from: attributes.span_id
|
|
||||||
- type: remove
|
|
||||||
field: attributes.trace_id
|
|
||||||
- type: remove
|
|
||||||
field: attributes.span_id
|
|
||||||
```
|
|
||||||
|
|
||||||
The operations in the above processor will parse the trace_id and span_id from log to opentelemetry log model and remove them from attributes.
|
|
@ -1,24 +1,21 @@
|
|||||||
If you use fluentD to collect logs in your stack with this tutotrial you will be able to send logs from fluentD to SigNoz.
|
## Collect Logs Using FluentD in SigNoz cloud
|
||||||
|
|
||||||
At SigNoz we use opentelemetry collector to recieve logs which supports the fluentforward protocol. So you can forward your logs from your fluentD agent to opentelemetry collector.
|
If you use fluentD to collect logs in your stack, you will be able to send logs from fluentD to SigNoz.
|
||||||
|
|
||||||
### Collect Logs Using FluentD in SigNoz cloud
|
At SigNoz, we use opentelemetry collector to recieve logs which supports the fluentforward protocol. So you can forward your logs from your fluentD agent to opentelemetry collector.
|
||||||
|
|
||||||
- Add otel collector binary to your VM by following this [guide](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/).
|
* Add otel collector binary to your VM by following this [guide](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/).
|
||||||
|
|
||||||
- Add fluentforward reciever to your `config.yaml`
|
|
||||||
|
|
||||||
|
* Add fluentforward reciever to your `config.yaml`
|
||||||
```yaml
|
```yaml
|
||||||
receivers:
|
receivers:
|
||||||
fluentforward:
|
fluentforward:
|
||||||
endpoint: 0.0.0.0:24224
|
endpoint: 0.0.0.0:24224
|
||||||
```
|
```
|
||||||
|
Here we have used port 24224 for listening in fluentforward protocol, but you can change it to a port you want.
|
||||||
Here we have used port 24224 for listing in fluentforward protocol, but you can change it to a port you want.
|
|
||||||
You can read more about fluentforward receiver [here](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/fluentforwardreceiver).
|
You can read more about fluentforward receiver [here](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/fluentforwardreceiver).
|
||||||
|
|
||||||
- Modify your `config.yaml` and add the above receiver
|
* Modify your `config.yaml` and add the above receiver
|
||||||
|
|
||||||
```yaml {4}
|
```yaml {4}
|
||||||
service:
|
service:
|
||||||
....
|
....
|
||||||
@ -28,17 +25,9 @@ At SigNoz we use opentelemetry collector to recieve logs which supports the flue
|
|||||||
exporters: [otlp]
|
exporters: [otlp]
|
||||||
```
|
```
|
||||||
|
|
||||||
- Change the fluentD config to forward the logs to otel collector.
|
* Add the following to your fluentD config to forward the logs to otel collector.
|
||||||
|
|
||||||
```
|
```
|
||||||
<source>
|
<match <directive>>
|
||||||
@type sample
|
|
||||||
sample [{"message": "my log data", "source": "myhost"}, {"message": "my log data 1", "source": "myhost1"}]
|
|
||||||
tag sample
|
|
||||||
rate 10000
|
|
||||||
</source>
|
|
||||||
|
|
||||||
<match sample>
|
|
||||||
@type forward
|
@type forward
|
||||||
send_timeout 60s
|
send_timeout 60s
|
||||||
recover_wait 10s
|
recover_wait 10s
|
||||||
@ -46,34 +35,32 @@ At SigNoz we use opentelemetry collector to recieve logs which supports the flue
|
|||||||
|
|
||||||
<server>
|
<server>
|
||||||
name myserver1
|
name myserver1
|
||||||
host otel-collector-host
|
host localhost
|
||||||
port 24224
|
port 24224
|
||||||
</server>
|
</server>
|
||||||
</match>
|
</match>
|
||||||
```
|
```
|
||||||
|
In this config we are matching a directive and forwarding logs to the otel collector which is listening on port 24224. Replace `<directive>` with your directive name.
|
||||||
|
Also we are assuming that you are running the fluentD binary on the host. If not, the value of `host` might change depending on your environment.
|
||||||
|
* Once you make this changes you can restart fluentD and otel-binary, and you will be able to see the logs in SigNoz.
|
||||||
|
|
||||||
|
* To properly transform your existing log model into opentelemetry [log](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md) model you can use the different processors provided by opentelemetry. ([link](https://signoz.io/docs/userguide/logs/#processors-available-for-processing-logs))
|
||||||
|
|
||||||
In this example we are generating sample logs and then forwarding them to the otel collector which is listening on port 24224.
|
eg:-
|
||||||
`otel-collector-host` has to be replaced by the host where otel-collector is running. For more info check [troubleshooting](../install/troubleshooting.md#signoz-otel-collector-address-grid).
|
|
||||||
|
|
||||||
- Once you make this changes you can restart fluentD and otel-binary, and you will be able to see the logs in SigNoz.
|
```yaml
|
||||||
|
processors:
|
||||||
|
logstransform:
|
||||||
|
operators:
|
||||||
|
- type: trace_parser
|
||||||
|
trace_id:
|
||||||
|
parse_from: attributes.trace_id
|
||||||
|
span_id:
|
||||||
|
parse_from: attributes.span_id
|
||||||
|
- type: remove
|
||||||
|
field: attributes.trace_id
|
||||||
|
- type: remove
|
||||||
|
field: attributes.span_id
|
||||||
|
```
|
||||||
|
|
||||||
- To properly transform your existing log model into opentelemetry [log](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md) model you can use the different processors provided by opentelemetry. [link](./logs.md#processors-available-for-processing-logs)
|
The operations in the above processor will parse the trace_id and span_id from log to opentelemetry log model and remove them from attributes.
|
||||||
|
|
||||||
eg:-
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
processors:
|
|
||||||
logstransform:
|
|
||||||
operators:
|
|
||||||
- type: trace_parser
|
|
||||||
trace_id:
|
|
||||||
parse_from: attributes.trace_id
|
|
||||||
span_id:
|
|
||||||
parse_from: attributes.span_id
|
|
||||||
- type: remove
|
|
||||||
field: attributes.trace_id
|
|
||||||
- type: remove
|
|
||||||
field: attributes.span_id
|
|
||||||
```
|
|
||||||
|
|
||||||
The operations in the above processor will parse the trace_id and span_id from log to opentelemetry log model and remove them from attributes.
|
|
@ -1,12 +1,13 @@
|
|||||||
If you use logstash to collect logs in your stack with this tutotrial you will be able to send logs from logstash to SigNoz.
|
## Collect Logs Using Logstash in SigNoz cloud
|
||||||
|
|
||||||
At SigNoz we use opentelemetry collector to recieve logs which supports the TCP protocol. So you can forward your logs from your logstash agent to opentelemetry collector
|
If you use logstash to collect logs in your stack, you will be able to send logs from Logstash to SigNoz.
|
||||||
|
|
||||||
## Steps to recieve logs from Logstash:
|
At SigNoz we use OpenTelemetry Collector to recieve logs which supports the TCP protocol. So you can forward your logs from the logstash agent to opentelemetry collector.
|
||||||
|
|
||||||
- Add fluentforward reciever to your `otel-collector-config.yaml` which is present inside `deploy/docker/clickhouse-setup`
|
* Add otel collector binary to your VM by following this [guide](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/).
|
||||||
|
|
||||||
```
|
* Add the reciever to your `config.yaml`
|
||||||
|
```yaml
|
||||||
receivers:
|
receivers:
|
||||||
tcplog/logstash:
|
tcplog/logstash:
|
||||||
max_log_size: 1MiB
|
max_log_size: 1MiB
|
||||||
@ -16,47 +17,32 @@ At SigNoz we use opentelemetry collector to recieve logs which supports the TCP
|
|||||||
add_attributes: false
|
add_attributes: false
|
||||||
operators: []
|
operators: []
|
||||||
```
|
```
|
||||||
|
Here we have used port 2255 for listening in TCP protocol, but you can change it to a port you want.
|
||||||
Here we have used port 2255 for listing in TCP protocol, but you can change it to a port you want.
|
|
||||||
You can read more about tcplog reciver [here](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/tcplogreceiver).
|
You can read more about tcplog reciver [here](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/tcplogreceiver).
|
||||||
|
|
||||||
- Update the pipleline for logs and make the following change in `otel-collector-config.yaml`
|
* Modify your `config.yaml` and add the above receiver
|
||||||
|
```yaml {4}
|
||||||
```
|
|
||||||
service:
|
service:
|
||||||
...
|
....
|
||||||
|
logs:
|
||||||
logs:
|
receivers: [otlp, tcplog/logstash]
|
||||||
receivers: [ otlp, tcplog/logstash ]
|
processors: [batch]
|
||||||
processors: [ batch ]
|
exporters: [otlp]
|
||||||
exporters: [ clickhouselogsexporter ]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Here we are adding our clickhouse exporter and creating a pipeline which will collect logs from `tcplog/logstash` receiver, processing it using batch processor and export it to clickhouse.
|
* Change the logstash config to forward the logs to otel collector.
|
||||||
|
|
||||||
- Expose the port in port for otel-collector in `docker-compose.yaml` file present in `deploy/docker/clickhouse-setup`
|
|
||||||
|
|
||||||
```
|
|
||||||
otel-collector:
|
|
||||||
...
|
|
||||||
ports:
|
|
||||||
- "2255:2255"
|
|
||||||
```
|
|
||||||
|
|
||||||
- Change the logstash config to forward the logs to otel collector.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
output {
|
output {
|
||||||
tcp {
|
tcp {
|
||||||
codec => json_lines # this is required otherwise it will send eveything in a single line
|
codec => json_lines # this is required otherwise it will send eveything in a single line
|
||||||
host => "otel-collector-host"
|
host => "localhost"
|
||||||
port => 2255
|
port => 2255
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
Here we are configuring logstash to send logs to otel-collector that we ran in the previous step, which is listening on port 2255.
|
||||||
|
Also we are assuming that you are running the logstash binary on the host. If not, the value of `host` might change depending on your environment.
|
||||||
|
|
||||||
In this example we are generating sample logs and then forwarding them to the otel collector which is listening on port 2255.
|
* Once you make this changes you can otel binary and logstash, and you will be able to see the logs in SigNoz.
|
||||||
`otel-collector-host` has to be replaced by the host where otel-collector is running. For more info check [troubleshooting](../install/troubleshooting.md#signoz-otel-collector-address-grid).
|
|
||||||
|
|
||||||
- Once you make this changes you can restart logstash and SignNoz, and you will be able to see the logs in SigNoz.
|
* To properly transform your existing log model into opentelemetry [log](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md) model you can use the different processors provided by opentelemetry ([link](https://signoz.io/docs/userguide/logs/#processors-available-for-processing-logs)).
|
||||||
- To properly transform your existing log model into opentelemetry [log](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md) model you can use the different processors provided by opentelemetry. [link](./logs.md#processors-available-for-processing-logs)
|
|
@ -1,8 +1,9 @@
|
|||||||
import { MDXProvider } from '@mdx-js/react';
|
import { Code, Pre } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||||
import Header from 'container/OnboardingContainer/common/Header/Header';
|
import Header from 'container/OnboardingContainer/common/Header/Header';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
|
||||||
import ConnectionStatus from '../common/LogsConnectionStatus/LogsConnectionStatus';
|
import ConnectionStatus from '../common/LogsConnectionStatus/LogsConnectionStatus';
|
||||||
import Post from './kubernetes.md';
|
import KubernetesDocs from './kubernetes.md';
|
||||||
|
|
||||||
export default function Kubernetes({
|
export default function Kubernetes({
|
||||||
activeStep,
|
activeStep,
|
||||||
@ -22,9 +23,14 @@ export default function Kubernetes({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="content-container">
|
<div className="content-container">
|
||||||
<MDXProvider>
|
<ReactMarkdown
|
||||||
<Post />
|
components={{
|
||||||
</MDXProvider>
|
pre: Pre,
|
||||||
|
code: Code,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{KubernetesDocs}
|
||||||
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
## Collect Kubernetes Pod Logs in SigNoz Cloud
|
## Collect Kubernetes Pod Logs in SigNoz Cloud
|
||||||
|
|
||||||
To collect logs from your kubernetes cluster, you will need to deploy k8s-infra chart. Please follow the guide [here](/docs/tutorial/kubernetes-infra-metrics/). Log collection of pods from all namespaces is enabled by default except for pods in `kube-system` and `hotrod`. To modify the log collection mechanism, please follow the guides below.
|
To collect logs from your kubernetes cluster, you will need to deploy k8s-infra chart. Please follow the guide [here](https://signoz.io/docs/tutorial/kubernetes-infra-metrics/). Log collection of pods from all namespaces is enabled by default except for pods in `kube-system` and `hotrod`. To modify the log collection mechanism, please follow the guides below.
|
||||||
|
|
||||||
- [Disable automatic pod logs collection](#steps-to-disable-automatic-pod-logs-collection)
|
- [Disable automatic pod logs collection](https://signoz.io/docs/userguide/collect_kubernetes_pod_logs/#steps-to-disable-automatic-pod-logs-collection)
|
||||||
- [Filter/Exclude logs collection](#steps-to-filterexclude-logs-collection)
|
- [Filter/Exclude logs collection](https://signoz.io/docs/userguide/collect_kubernetes_pod_logs/#steps-to-filterexclude-logs-collection)
|
||||||
|
@ -35,16 +35,6 @@ const supportedLogTypes = [
|
|||||||
id: 'application_logs_log_file',
|
id: 'application_logs_log_file',
|
||||||
imgURL: `Logos/software-window.svg`,
|
imgURL: `Logos/software-window.svg`,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'NodeJS Winston Logs ',
|
|
||||||
id: 'nodejs',
|
|
||||||
imgURL: `Logos/node-js.svg`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Application Logs using OTEL SDK',
|
|
||||||
id: 'application_logs_otel_sdk',
|
|
||||||
imgURL: `Logos/cmd-terminal.svg`,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'Logs from existing collectors',
|
name: 'Logs from existing collectors',
|
||||||
id: 'existing_collectors',
|
id: 'existing_collectors',
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { MDXProvider } from '@mdx-js/react';
|
import { Code, Pre } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||||
import Header from 'container/OnboardingContainer/common/Header/Header';
|
import Header from 'container/OnboardingContainer/common/Header/Header';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
|
||||||
import ConnectionStatus from '../common/LogsConnectionStatus/LogsConnectionStatus';
|
import ConnectionStatus from '../common/LogsConnectionStatus/LogsConnectionStatus';
|
||||||
import Post from './nodejs.md';
|
import NodeJsDocs from './nodejs.md';
|
||||||
|
|
||||||
export default function Nodejs({
|
export default function Nodejs({
|
||||||
activeStep,
|
activeStep,
|
||||||
@ -22,9 +23,14 @@ export default function Nodejs({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="content-container">
|
<div className="content-container">
|
||||||
<MDXProvider>
|
<ReactMarkdown
|
||||||
<Post />
|
components={{
|
||||||
</MDXProvider>
|
pre: Pre,
|
||||||
|
code: Code,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{NodeJsDocs}
|
||||||
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { MDXProvider } from '@mdx-js/react';
|
import { Code, Pre } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||||
import Header from 'container/OnboardingContainer/common/Header/Header';
|
import Header from 'container/OnboardingContainer/common/Header/Header';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
|
||||||
import ConnectionStatus from '../common/LogsConnectionStatus/LogsConnectionStatus';
|
import ConnectionStatus from '../common/LogsConnectionStatus/LogsConnectionStatus';
|
||||||
import Post from './syslogs.md';
|
import SysLogsDocs from './syslogs.md';
|
||||||
|
|
||||||
export default function SysLogs({
|
export default function SysLogs({
|
||||||
activeStep,
|
activeStep,
|
||||||
@ -22,9 +23,14 @@ export default function SysLogs({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="content-container">
|
<div className="content-container">
|
||||||
<MDXProvider>
|
<ReactMarkdown
|
||||||
<Post />
|
components={{
|
||||||
</MDXProvider>
|
pre: Pre,
|
||||||
|
code: Code,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{SysLogsDocs}
|
||||||
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
## Collect Syslogs in SigNoz cloud
|
## Collect Syslogs in SigNoz cloud
|
||||||
|
|
||||||
If you don’t already have a SigNoz cloud account, you can sign up [here](https://signoz.io/teams/).
|
|
||||||
|
|
||||||
<Tabs>
|
|
||||||
<TabItem value="VM" label="VM" default>
|
|
||||||
|
|
||||||
- Add otel collector binary to your VM by following this [guide](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/).
|
- Add otel collector binary to your VM by following this [guide](https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/).
|
||||||
|
|
||||||
- Add the syslog reciever to `config.yaml` to otel-collector.
|
- Add the syslog reciever to `config.yaml` to otel-collector.
|
||||||
|
|
||||||
```yaml {2-10}
|
```yaml {2-10}
|
||||||
@ -22,7 +18,7 @@ If you don’t already have a SigNoz cloud account, you can sign up [here](https
|
|||||||
```
|
```
|
||||||
|
|
||||||
Here we are collecting the logs and moving message from attributes to body using operators that are available.
|
Here we are collecting the logs and moving message from attributes to body using operators that are available.
|
||||||
You can read more about operators [here](./logs.md#operators-for-parsing-and-manipulating-logs).
|
You can read more about operators [here](https://signoz.io/docs/userguide/logs/#operators-for-parsing-and-manipulating-logs).
|
||||||
|
|
||||||
For more configurations that are available for syslog receiver please check [here](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/syslogreceiver).
|
For more configurations that are available for syslog receiver please check [here](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/syslogreceiver).
|
||||||
|
|
||||||
@ -70,14 +66,10 @@ If you don’t already have a SigNoz cloud account, you can sign up [here](https
|
|||||||
action.resumeRetryCount="10"
|
action.resumeRetryCount="10"
|
||||||
queue.type="linkedList" queue.size="10000" template="UTCTraditionalForwardFormat")
|
queue.type="linkedList" queue.size="10000" template="UTCTraditionalForwardFormat")
|
||||||
```
|
```
|
||||||
|
So that you have retries and queue in place to de-couple the sending from other logging action. Also, we are assuming that you are running the otel binary on the same host. If not, the value of target might change depending on your environment.
|
||||||
So that you have retires and queue in place to de-couple the sending from the other logging action.
|
|
||||||
|
|
||||||
The value of `target` might vary depending on where SigNoz is deployed, since it is deployed on the same host I am using `0.0.0.0` for more help you can visit [here](../install/troubleshooting.md#signoz-otel-collector-address-grid).
|
|
||||||
|
|
||||||
- Now restart your rsyslog service by running `sudo systemctl restart rsyslog.service`
|
- Now restart your rsyslog service by running `sudo systemctl restart rsyslog.service`
|
||||||
- You can check the status of service by running `sudo systemctl status rsyslog.service`
|
|
||||||
- If there are no errors your logs will be visible on SigNoz UI.
|
|
||||||
|
|
||||||
</TabItem>
|
- You can check the status of service by running `sudo systemctl status rsyslog.service`
|
||||||
</Tabs>
|
|
||||||
|
- If there are no errors your logs will be visible on SigNoz UI.
|
||||||
|
@ -43,21 +43,21 @@ const useCases = {
|
|||||||
id: ModulesMap.APM,
|
id: ModulesMap.APM,
|
||||||
title: 'Application Monitoring',
|
title: 'Application Monitoring',
|
||||||
desc:
|
desc:
|
||||||
'Monitor performance of your applications & troubleshoot problems by installing within your infra.',
|
'Monitor application metrics like p99 latency, error rates, external API calls, and db calls.',
|
||||||
stepDesc: defaultStepDesc,
|
stepDesc: defaultStepDesc,
|
||||||
},
|
},
|
||||||
LogsManagement: {
|
LogsManagement: {
|
||||||
id: ModulesMap.LogsManagement,
|
id: ModulesMap.LogsManagement,
|
||||||
title: 'Logs Management',
|
title: 'Logs Management',
|
||||||
desc:
|
desc:
|
||||||
'Easily search and filter logs with query builder and automatically detect logs from K8s cluster.',
|
'Easily filter and query logs, build dashboards and alerts based on attributes in logs',
|
||||||
stepDesc: 'Choose the logs that you want to receive on SigNoz',
|
stepDesc: 'Choose the logs that you want to receive on SigNoz',
|
||||||
},
|
},
|
||||||
InfrastructureMonitoring: {
|
InfrastructureMonitoring: {
|
||||||
id: ModulesMap.InfrastructureMonitoring,
|
id: ModulesMap.InfrastructureMonitoring,
|
||||||
title: 'Infrastructure Monitoring',
|
title: 'Infrastructure Monitoring',
|
||||||
desc:
|
desc:
|
||||||
'Easily search and filter logs with query builder and automatically detect logs from K8s cluster.',
|
'Monitor Kubernetes infrastructure metrics, hostmetrics, or metrics of any third-party integration',
|
||||||
stepDesc: defaultStepDesc,
|
stepDesc: defaultStepDesc,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
import { Form } from 'antd';
|
||||||
|
import { initialQueryBuilderFormValuesMap } from 'constants/queryBuilder';
|
||||||
|
import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch';
|
||||||
|
import isEqual from 'lodash-es/isEqual';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { TagFilter } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
|
import { ProcessorFormField } from '../../AddNewProcessor/config';
|
||||||
|
import { formValidationRules } from '../../config';
|
||||||
|
import { FormLabelStyle } from '../styles';
|
||||||
|
|
||||||
|
function TagFilterInput({
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
placeholder,
|
||||||
|
}: TagFilterInputProps): JSX.Element {
|
||||||
|
const query = { ...initialQueryBuilderFormValuesMap.logs };
|
||||||
|
if (value) {
|
||||||
|
query.filters = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const onQueryChange = (newValue: TagFilter): void => {
|
||||||
|
// Avoid unnecessary onChange calls
|
||||||
|
if (!isEqual(newValue, query.filters)) {
|
||||||
|
onChange(newValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<QueryBuilderSearch
|
||||||
|
query={query}
|
||||||
|
onChange={onQueryChange}
|
||||||
|
placeholder={placeholder}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TagFilterInputProps {
|
||||||
|
onChange: (filter: TagFilter) => void;
|
||||||
|
value: TagFilter;
|
||||||
|
placeholder: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function FilterInput({ fieldData }: FilterInputProps): JSX.Element {
|
||||||
|
const { t } = useTranslation('pipeline');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
required={false}
|
||||||
|
label={<FormLabelStyle>{fieldData.fieldName}</FormLabelStyle>}
|
||||||
|
key={fieldData.id}
|
||||||
|
rules={formValidationRules}
|
||||||
|
name={fieldData.name}
|
||||||
|
>
|
||||||
|
{/* Antd form will supply value and onChange to <TagFilterInput /> here.
|
||||||
|
// @ts-ignore */}
|
||||||
|
<TagFilterInput placeholder={t(fieldData.placeholder)} />
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
interface FilterInputProps {
|
||||||
|
fieldData: ProcessorFormField;
|
||||||
|
}
|
||||||
|
export default FilterInput;
|
@ -1,31 +0,0 @@
|
|||||||
import { Form, Input } from 'antd';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
import { ProcessorFormField } from '../../AddNewProcessor/config';
|
|
||||||
import { formValidationRules } from '../../config';
|
|
||||||
import { FormLabelStyle } from '../styles';
|
|
||||||
|
|
||||||
function FilterSearch({ fieldData }: FilterSearchProps): JSX.Element {
|
|
||||||
const { t } = useTranslation('pipeline');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form.Item
|
|
||||||
required={false}
|
|
||||||
label={<FormLabelStyle>{fieldData.fieldName}</FormLabelStyle>}
|
|
||||||
key={fieldData.id}
|
|
||||||
rules={formValidationRules}
|
|
||||||
name={fieldData.name}
|
|
||||||
>
|
|
||||||
<Input.Search
|
|
||||||
id={fieldData.id.toString()}
|
|
||||||
name={fieldData.name}
|
|
||||||
placeholder={t(fieldData.placeholder)}
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
interface FilterSearchProps {
|
|
||||||
fieldData: ProcessorFormField;
|
|
||||||
}
|
|
||||||
export default FilterSearch;
|
|
@ -0,0 +1,24 @@
|
|||||||
|
import './styles.scss';
|
||||||
|
|
||||||
|
import { queryFilterTags } from 'hooks/queryBuilder/useTag';
|
||||||
|
import { PipelineData } from 'types/api/pipeline/def';
|
||||||
|
|
||||||
|
function PipelineFilterPreview({
|
||||||
|
filter,
|
||||||
|
}: PipelineFilterPreviewProps): JSX.Element {
|
||||||
|
return (
|
||||||
|
<div className="pipeline-filter-preview-container">
|
||||||
|
{queryFilterTags(filter).map((tag) => (
|
||||||
|
<div className="pipeline-filter-preview-condition" key={tag}>
|
||||||
|
{tag}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PipelineFilterPreviewProps {
|
||||||
|
filter: PipelineData['filter'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PipelineFilterPreview;
|
@ -0,0 +1,10 @@
|
|||||||
|
.pipeline-filter-preview-condition {
|
||||||
|
padding: 0 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pipeline-filter-preview-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.4em;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
@ -4,6 +4,7 @@ import { PipelineData, ProcessorData } from 'types/api/pipeline/def';
|
|||||||
|
|
||||||
import { PipelineIndexIcon } from '../AddNewProcessor/styles';
|
import { PipelineIndexIcon } from '../AddNewProcessor/styles';
|
||||||
import { ColumnDataStyle, ListDataStyle, ProcessorIndexIcon } from '../styles';
|
import { ColumnDataStyle, ListDataStyle, ProcessorIndexIcon } from '../styles';
|
||||||
|
import PipelineFilterPreview from './PipelineFilterPreview';
|
||||||
|
|
||||||
const componentMap: ComponentMap = {
|
const componentMap: ComponentMap = {
|
||||||
orderId: ({ record }) => <PipelineIndexIcon>{record}</PipelineIndexIcon>,
|
orderId: ({ record }) => <PipelineIndexIcon>{record}</PipelineIndexIcon>,
|
||||||
@ -14,6 +15,7 @@ const componentMap: ComponentMap = {
|
|||||||
),
|
),
|
||||||
id: ({ record }) => <ProcessorIndexIcon>{record}</ProcessorIndexIcon>,
|
id: ({ record }) => <ProcessorIndexIcon>{record}</ProcessorIndexIcon>,
|
||||||
name: ({ record }) => <ListDataStyle>{record}</ListDataStyle>,
|
name: ({ record }) => <ListDataStyle>{record}</ListDataStyle>,
|
||||||
|
filter: ({ record }) => <PipelineFilterPreview filter={record} />,
|
||||||
};
|
};
|
||||||
|
|
||||||
function TableComponents({
|
function TableComponents({
|
||||||
@ -31,7 +33,9 @@ type ComponentMap = {
|
|||||||
[key: string]: React.FC<{ record: Record }>;
|
[key: string]: React.FC<{ record: Record }>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Record = PipelineData['orderId'] & ProcessorData;
|
export type Record = PipelineData['orderId'] &
|
||||||
|
PipelineData['filter'] &
|
||||||
|
ProcessorData;
|
||||||
|
|
||||||
interface TableComponentsProps {
|
interface TableComponentsProps {
|
||||||
columnKey: string;
|
columnKey: string;
|
||||||
|
@ -8,15 +8,16 @@ import {
|
|||||||
import DeploymentStage from '../Layouts/ChangeHistory/DeploymentStage';
|
import DeploymentStage from '../Layouts/ChangeHistory/DeploymentStage';
|
||||||
import DeploymentTime from '../Layouts/ChangeHistory/DeploymentTime';
|
import DeploymentTime from '../Layouts/ChangeHistory/DeploymentTime';
|
||||||
import DescriptionTextArea from './AddNewPipeline/FormFields/DescriptionTextArea';
|
import DescriptionTextArea from './AddNewPipeline/FormFields/DescriptionTextArea';
|
||||||
|
import FilterInput from './AddNewPipeline/FormFields/FilterInput';
|
||||||
import NameInput from './AddNewPipeline/FormFields/NameInput';
|
import NameInput from './AddNewPipeline/FormFields/NameInput';
|
||||||
|
|
||||||
export const pipelineFields = [
|
export const pipelineFields = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
fieldName: 'Filter',
|
fieldName: 'Filter',
|
||||||
placeholder: 'search_pipeline_placeholder',
|
placeholder: 'pipeline_filter_placeholder',
|
||||||
name: 'filter',
|
name: 'filter',
|
||||||
component: NameInput,
|
component: FilterInput,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
|
@ -1,7 +1,33 @@
|
|||||||
import { Pipeline, PipelineData } from 'types/api/pipeline/def';
|
import { Pipeline, PipelineData } from 'types/api/pipeline/def';
|
||||||
|
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
|
import { TagFilter } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
export const configurationVersion = '1.0';
|
export const configurationVersion = '1.0';
|
||||||
|
|
||||||
|
export function mockPipelineFilter(
|
||||||
|
key: string,
|
||||||
|
op: string,
|
||||||
|
value: string,
|
||||||
|
): TagFilter {
|
||||||
|
return {
|
||||||
|
op: 'AND',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: `${key}-${value}`,
|
||||||
|
key: {
|
||||||
|
key,
|
||||||
|
dataType: DataTypes.String,
|
||||||
|
type: '',
|
||||||
|
isColumn: false,
|
||||||
|
isJSON: false,
|
||||||
|
},
|
||||||
|
op,
|
||||||
|
value,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export const pipelineMockData: Array<PipelineData> = [
|
export const pipelineMockData: Array<PipelineData> = [
|
||||||
{
|
{
|
||||||
id: '4453c8b0-c0fd-42bf-bf09-7cc1b04ccdc9',
|
id: '4453c8b0-c0fd-42bf-bf09-7cc1b04ccdc9',
|
||||||
@ -10,7 +36,7 @@ export const pipelineMockData: Array<PipelineData> = [
|
|||||||
alias: 'apachecommonparser',
|
alias: 'apachecommonparser',
|
||||||
description: 'This is a desc',
|
description: 'This is a desc',
|
||||||
enabled: false,
|
enabled: false,
|
||||||
filter: 'attributes.source == nginx',
|
filter: mockPipelineFilter('source', '=', 'nginx'),
|
||||||
config: [
|
config: [
|
||||||
{
|
{
|
||||||
orderId: 1,
|
orderId: 1,
|
||||||
@ -43,7 +69,7 @@ export const pipelineMockData: Array<PipelineData> = [
|
|||||||
alias: 'movingpipelinenew',
|
alias: 'movingpipelinenew',
|
||||||
description: 'This is a desc of move',
|
description: 'This is a desc of move',
|
||||||
enabled: false,
|
enabled: false,
|
||||||
filter: 'attributes.method == POST',
|
filter: mockPipelineFilter('method', '=', 'POST'),
|
||||||
config: [
|
config: [
|
||||||
{
|
{
|
||||||
orderId: 1,
|
orderId: 1,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
import { I18nextProvider } from 'react-i18next';
|
import { I18nextProvider } from 'react-i18next';
|
||||||
|
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { MemoryRouter } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
import i18n from 'ReactI18';
|
import i18n from 'ReactI18';
|
||||||
@ -27,25 +28,36 @@ beforeAll(() => {
|
|||||||
matchMedia();
|
matchMedia();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const queryClient = new QueryClient({
|
||||||
|
defaultOptions: {
|
||||||
|
queries: {
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
describe('PipelinePage container test', () => {
|
describe('PipelinePage container test', () => {
|
||||||
it('should render AddNewPipeline section', () => {
|
it('should render AddNewPipeline section', () => {
|
||||||
const setActionType = jest.fn();
|
const setActionType = jest.fn();
|
||||||
const selectedPipelineData = pipelineMockData[0];
|
const selectedPipelineData = pipelineMockData[0];
|
||||||
const isActionType = 'add-pipeline';
|
const isActionType = 'add-pipeline';
|
||||||
|
|
||||||
const { asFragment } = render(
|
const { asFragment } = render(
|
||||||
<MemoryRouter>
|
<MemoryRouter>
|
||||||
<Provider store={store}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<I18nextProvider i18n={i18n}>
|
<Provider store={store}>
|
||||||
<AddNewPipeline
|
<I18nextProvider i18n={i18n}>
|
||||||
isActionType={isActionType}
|
<AddNewPipeline
|
||||||
setActionType={setActionType}
|
isActionType={isActionType}
|
||||||
selectedPipelineData={selectedPipelineData}
|
setActionType={setActionType}
|
||||||
setShowSaveButton={jest.fn()}
|
selectedPipelineData={selectedPipelineData}
|
||||||
setCurrPipelineData={jest.fn()}
|
setShowSaveButton={jest.fn()}
|
||||||
currPipelineData={pipelineMockData}
|
setCurrPipelineData={jest.fn()}
|
||||||
/>
|
currPipelineData={pipelineMockData}
|
||||||
</I18nextProvider>
|
/>
|
||||||
</Provider>
|
</I18nextProvider>
|
||||||
|
</Provider>
|
||||||
|
</QueryClientProvider>
|
||||||
</MemoryRouter>,
|
</MemoryRouter>,
|
||||||
);
|
);
|
||||||
expect(asFragment()).toMatchSnapshot();
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { pipelineMockData } from '../mocks/pipeline';
|
import { mockPipelineFilter, pipelineMockData } from '../mocks/pipeline';
|
||||||
import {
|
import {
|
||||||
processorFields,
|
processorFields,
|
||||||
processorTypes,
|
processorTypes,
|
||||||
@ -68,7 +68,7 @@ describe('Utils testing of Pipeline Page', () => {
|
|||||||
...pipelineMockData[findRecordIndex],
|
...pipelineMockData[findRecordIndex],
|
||||||
name: 'updated name',
|
name: 'updated name',
|
||||||
description: 'changed description',
|
description: 'changed description',
|
||||||
filter: 'value == test',
|
filter: mockPipelineFilter('value', '=', 'test'),
|
||||||
tags: ['test'],
|
tags: ['test'],
|
||||||
};
|
};
|
||||||
const editedData = getEditedDataSource(
|
const editedData = getEditedDataSource(
|
||||||
|
@ -5,6 +5,7 @@ import { MAX_FORMULAS, MAX_QUERIES } from 'constants/queryBuilder';
|
|||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
// ** Constants
|
// ** Constants
|
||||||
import { memo, useEffect, useMemo } from 'react';
|
import { memo, useEffect, useMemo } from 'react';
|
||||||
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
|
|
||||||
// ** Components
|
// ** Components
|
||||||
import { Formula, Query } from './components';
|
import { Formula, Query } from './components';
|
||||||
@ -79,11 +80,27 @@ export const QueryBuilder = memo(function QueryBuilder({
|
|||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
))}
|
))}
|
||||||
{currentQuery.builder.queryFormulas.map((formula, index) => (
|
{currentQuery.builder.queryFormulas.map((formula, index) => {
|
||||||
<Col key={formula.queryName} span={24}>
|
const isAllMetricDataSource = currentQuery.builder.queryData.every(
|
||||||
<Formula formula={formula} index={index} />
|
(query) => query.dataSource === DataSource.METRICS,
|
||||||
</Col>
|
);
|
||||||
))}
|
|
||||||
|
const query =
|
||||||
|
currentQuery.builder.queryData[index] ||
|
||||||
|
currentQuery.builder.queryData[0];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Col key={formula.queryName} span={24}>
|
||||||
|
<Formula
|
||||||
|
filterConfigs={filterConfigs}
|
||||||
|
query={query}
|
||||||
|
isAdditionalFilterEnable={isAllMetricDataSource}
|
||||||
|
formula={formula}
|
||||||
|
index={index}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</Row>
|
</Row>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
|
@ -21,13 +21,13 @@ export const AdditionalFiltersToggler = memo(function AdditionalFiltersToggler({
|
|||||||
setIsOpenedFilters((prevState) => !prevState);
|
setIsOpenedFilters((prevState) => !prevState);
|
||||||
};
|
};
|
||||||
|
|
||||||
const filtersTexts: ReactNode = listOfAdditionalFilter.map((str, index) => {
|
const filtersTexts: ReactNode = listOfAdditionalFilter?.map((str, index) => {
|
||||||
const isNextLast = index + 1 === listOfAdditionalFilter.length - 1;
|
const isNextLast = index + 1 === listOfAdditionalFilter.length - 1;
|
||||||
|
|
||||||
if (index === listOfAdditionalFilter.length - 1) {
|
if (index === listOfAdditionalFilter.length - 1) {
|
||||||
return (
|
return (
|
||||||
<Fragment key={str}>
|
<Fragment key={str}>
|
||||||
{listOfAdditionalFilter.length > 1 && 'and'}{' '}
|
{listOfAdditionalFilter?.length > 1 && 'and'}{' '}
|
||||||
<StyledLink>{str.toUpperCase()}</StyledLink>
|
<StyledLink>{str.toUpperCase()}</StyledLink>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
import { IBuilderFormula } from 'types/api/queryBuilder/queryBuilderData';
|
import { QueryBuilderProps } from 'container/QueryBuilder/QueryBuilder.interfaces';
|
||||||
|
import {
|
||||||
|
IBuilderFormula,
|
||||||
|
IBuilderQuery,
|
||||||
|
} from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
export type FormulaProps = { formula: IBuilderFormula; index: number };
|
export type FormulaProps = {
|
||||||
|
formula: IBuilderFormula;
|
||||||
|
index: number;
|
||||||
|
query: IBuilderQuery;
|
||||||
|
filterConfigs: Partial<QueryBuilderProps['filterConfigs']>;
|
||||||
|
isAdditionalFilterEnable: boolean;
|
||||||
|
};
|
||||||
|
@ -1,22 +1,45 @@
|
|||||||
import { Col, Input } from 'antd';
|
import { Col, Input, Row } from 'antd';
|
||||||
// ** Components
|
// ** Components
|
||||||
import { ListItemWrapper, ListMarker } from 'container/QueryBuilder/components';
|
import {
|
||||||
|
FilterLabel,
|
||||||
|
ListItemWrapper,
|
||||||
|
ListMarker,
|
||||||
|
} from 'container/QueryBuilder/components';
|
||||||
|
import HavingFilter from 'container/QueryBuilder/filters/Formula/Having/HavingFilter';
|
||||||
|
import LimitFilter from 'container/QueryBuilder/filters/Formula/Limit/Limit';
|
||||||
|
import OrderByFilter from 'container/QueryBuilder/filters/Formula/OrderBy/OrderByFilter';
|
||||||
// ** Hooks
|
// ** Hooks
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
import { ChangeEvent, useCallback } from 'react';
|
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
|
||||||
|
import { ChangeEvent, useCallback, useMemo } from 'react';
|
||||||
import { IBuilderFormula } from 'types/api/queryBuilder/queryBuilderData';
|
import { IBuilderFormula } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
|
import { AdditionalFiltersToggler } from '../AdditionalFiltersToggler';
|
||||||
// ** Types
|
// ** Types
|
||||||
import { FormulaProps } from './Formula.interfaces';
|
import { FormulaProps } from './Formula.interfaces';
|
||||||
|
|
||||||
const { TextArea } = Input;
|
export function Formula({
|
||||||
|
index,
|
||||||
export function Formula({ index, formula }: FormulaProps): JSX.Element {
|
formula,
|
||||||
|
filterConfigs,
|
||||||
|
query,
|
||||||
|
isAdditionalFilterEnable,
|
||||||
|
}: FormulaProps): JSX.Element {
|
||||||
const {
|
const {
|
||||||
removeQueryBuilderEntityByIndex,
|
removeQueryBuilderEntityByIndex,
|
||||||
handleSetFormulaData,
|
handleSetFormulaData,
|
||||||
} = useQueryBuilder();
|
} = useQueryBuilder();
|
||||||
|
|
||||||
|
const {
|
||||||
|
listOfAdditionalFormulaFilters,
|
||||||
|
handleChangeFormulaData,
|
||||||
|
} = useQueryOperations({
|
||||||
|
index,
|
||||||
|
query,
|
||||||
|
filterConfigs,
|
||||||
|
formula,
|
||||||
|
});
|
||||||
|
|
||||||
const handleDelete = useCallback(() => {
|
const handleDelete = useCallback(() => {
|
||||||
removeQueryBuilderEntityByIndex('queryFormulas', index);
|
removeQueryBuilderEntityByIndex('queryFormulas', index);
|
||||||
}, [index, removeQueryBuilderEntityByIndex]);
|
}, [index, removeQueryBuilderEntityByIndex]);
|
||||||
@ -43,6 +66,75 @@ export function Formula({ index, formula }: FormulaProps): JSX.Element {
|
|||||||
[index, formula, handleSetFormulaData],
|
[index, formula, handleSetFormulaData],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleChangeLimit = useCallback(
|
||||||
|
(value: IBuilderFormula['limit']) => {
|
||||||
|
handleChangeFormulaData('limit', value);
|
||||||
|
},
|
||||||
|
[handleChangeFormulaData],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleChangeHavingFilter = useCallback(
|
||||||
|
(value: IBuilderFormula['having']) => {
|
||||||
|
handleChangeFormulaData('having', value);
|
||||||
|
},
|
||||||
|
[handleChangeFormulaData],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleChangeOrderByFilter = useCallback(
|
||||||
|
(value: IBuilderFormula['orderBy']) => {
|
||||||
|
handleChangeFormulaData('orderBy', value);
|
||||||
|
},
|
||||||
|
[handleChangeFormulaData],
|
||||||
|
);
|
||||||
|
|
||||||
|
const renderAdditionalFilters = useMemo(
|
||||||
|
() => (
|
||||||
|
<>
|
||||||
|
<Col span={11}>
|
||||||
|
<Row gutter={[11, 5]}>
|
||||||
|
<Col flex="5.93rem">
|
||||||
|
<FilterLabel label="Limit" />
|
||||||
|
</Col>
|
||||||
|
<Col flex="1 1 12.5rem">
|
||||||
|
<LimitFilter formula={formula} onChange={handleChangeLimit} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
<Col span={11}>
|
||||||
|
<Row gutter={[11, 5]}>
|
||||||
|
<Col flex="5.93rem">
|
||||||
|
<FilterLabel label="HAVING" />
|
||||||
|
</Col>
|
||||||
|
<Col flex="1 1 12.5rem">
|
||||||
|
<HavingFilter formula={formula} onChange={handleChangeHavingFilter} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
<Col span={11}>
|
||||||
|
<Row gutter={[11, 5]}>
|
||||||
|
<Col flex="5.93rem">
|
||||||
|
<FilterLabel label="Order by" />
|
||||||
|
</Col>
|
||||||
|
<Col flex="1 1 12.5rem">
|
||||||
|
<OrderByFilter
|
||||||
|
query={query}
|
||||||
|
formula={formula}
|
||||||
|
onChange={handleChangeOrderByFilter}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
[
|
||||||
|
formula,
|
||||||
|
handleChangeHavingFilter,
|
||||||
|
handleChangeLimit,
|
||||||
|
handleChangeOrderByFilter,
|
||||||
|
query,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ListItemWrapper onDelete={handleDelete}>
|
<ListItemWrapper onDelete={handleDelete}>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
@ -54,7 +146,7 @@ export function Formula({ index, formula }: FormulaProps): JSX.Element {
|
|||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<TextArea
|
<Input.TextArea
|
||||||
name="expression"
|
name="expression"
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
size="middle"
|
size="middle"
|
||||||
@ -71,6 +163,17 @@ export function Formula({ index, formula }: FormulaProps): JSX.Element {
|
|||||||
addonBefore="Legend Format"
|
addonBefore="Legend Format"
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
{isAdditionalFilterEnable && (
|
||||||
|
<Col span={24}>
|
||||||
|
<AdditionalFiltersToggler
|
||||||
|
listOfAdditionalFilter={listOfAdditionalFormulaFilters}
|
||||||
|
>
|
||||||
|
<Row gutter={[0, 11]} justify="space-between">
|
||||||
|
{renderAdditionalFilters}
|
||||||
|
</Row>
|
||||||
|
</AdditionalFiltersToggler>
|
||||||
|
</Col>
|
||||||
|
)}
|
||||||
</ListItemWrapper>
|
</ListItemWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ import AggregateEveryFilter from 'container/QueryBuilder/filters/AggregateEveryF
|
|||||||
import LimitFilter from 'container/QueryBuilder/filters/LimitFilter/LimitFilter';
|
import LimitFilter from 'container/QueryBuilder/filters/LimitFilter/LimitFilter';
|
||||||
import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch';
|
import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch';
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
import { useQueryOperations } from 'hooks/queryBuilder/useQueryOperations';
|
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
|
||||||
// ** Hooks
|
// ** Hooks
|
||||||
import { ChangeEvent, memo, ReactNode, useCallback } from 'react';
|
import { ChangeEvent, memo, ReactNode, useCallback } from 'react';
|
||||||
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
@ -22,6 +22,7 @@ import {
|
|||||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
import { ExtendedSelectOption } from 'types/common/select';
|
import { ExtendedSelectOption } from 'types/common/select';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
import { transformToUpperCase } from 'utils/transformToUpperCase';
|
import { transformToUpperCase } from 'utils/transformToUpperCase';
|
||||||
|
|
||||||
import { selectStyle } from '../QueryBuilderSearch/config';
|
import { selectStyle } from '../QueryBuilderSearch/config';
|
||||||
@ -172,6 +173,7 @@ export const AggregatorFilter = memo(function AggregatorFilter({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<AutoComplete
|
<AutoComplete
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
style={selectStyle}
|
style={selectStyle}
|
||||||
showArrow={false}
|
showArrow={false}
|
||||||
|
@ -0,0 +1,198 @@
|
|||||||
|
import { Select } from 'antd';
|
||||||
|
import { HAVING_OPERATORS, initialHavingValues } from 'constants/queryBuilder';
|
||||||
|
import { HavingFilterTag } from 'container/QueryBuilder/components';
|
||||||
|
import { useTagValidation } from 'hooks/queryBuilder/useTagValidation';
|
||||||
|
import {
|
||||||
|
transformFromStringToHaving,
|
||||||
|
transformHavingToStringValue,
|
||||||
|
} from 'lib/query/transformQueryBuilderData';
|
||||||
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
import { Having, HavingForm } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
import { SelectOption } from 'types/common/select';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
|
import { getHavingObject, isValidHavingValue } from '../../utils';
|
||||||
|
import { HavingFilterProps, HavingTagRenderProps } from './types';
|
||||||
|
|
||||||
|
function HavingFilter({ formula, onChange }: HavingFilterProps): JSX.Element {
|
||||||
|
const { having } = formula;
|
||||||
|
const [searchText, setSearchText] = useState<string>('');
|
||||||
|
const [localValues, setLocalValues] = useState<string[]>([]);
|
||||||
|
const [currentFormValue, setCurrentFormValue] = useState<HavingForm>(
|
||||||
|
initialHavingValues,
|
||||||
|
);
|
||||||
|
const [options, setOptions] = useState<SelectOption<string, string>[]>([]);
|
||||||
|
|
||||||
|
const { isMulti } = useTagValidation(
|
||||||
|
currentFormValue.op,
|
||||||
|
currentFormValue.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
const columnName = formula.expression.toUpperCase();
|
||||||
|
|
||||||
|
const aggregatorOptions: SelectOption<string, string>[] = useMemo(
|
||||||
|
() => [{ label: columnName, value: columnName }],
|
||||||
|
[columnName],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleUpdateTag = useCallback(
|
||||||
|
(value: string) => {
|
||||||
|
const filteredValues = localValues.filter(
|
||||||
|
(currentValue) => currentValue !== value,
|
||||||
|
);
|
||||||
|
const having: Having[] = filteredValues.map(transformFromStringToHaving);
|
||||||
|
|
||||||
|
onChange(having);
|
||||||
|
setSearchText(value);
|
||||||
|
},
|
||||||
|
[localValues, onChange],
|
||||||
|
);
|
||||||
|
|
||||||
|
const generateOptions = useCallback(
|
||||||
|
(currentString: string) => {
|
||||||
|
const [aggregator = '', op = '', ...restValue] = currentString.split(' ');
|
||||||
|
let newOptions: SelectOption<string, string>[] = [];
|
||||||
|
|
||||||
|
const isAggregatorExist = columnName
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(currentString.toLowerCase());
|
||||||
|
|
||||||
|
const isAggregatorChosen = aggregator === columnName;
|
||||||
|
|
||||||
|
if (isAggregatorExist || aggregator === '') {
|
||||||
|
newOptions = aggregatorOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((isAggregatorChosen && op === '') || op) {
|
||||||
|
const filteredOperators = HAVING_OPERATORS.filter((num) =>
|
||||||
|
num.toLowerCase().includes(op.toLowerCase()),
|
||||||
|
);
|
||||||
|
|
||||||
|
newOptions = filteredOperators.map((opt) => ({
|
||||||
|
label: `${columnName} ${opt} ${restValue && restValue.join(' ')}`,
|
||||||
|
value: `${columnName} ${opt} ${restValue && restValue.join(' ')}`,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
setOptions(newOptions);
|
||||||
|
},
|
||||||
|
[aggregatorOptions, columnName],
|
||||||
|
);
|
||||||
|
|
||||||
|
const parseSearchText = useCallback(
|
||||||
|
(text: string) => {
|
||||||
|
const { columnName, op, value } = getHavingObject(text);
|
||||||
|
setCurrentFormValue({ columnName, op, value });
|
||||||
|
|
||||||
|
generateOptions(text);
|
||||||
|
},
|
||||||
|
[generateOptions],
|
||||||
|
);
|
||||||
|
|
||||||
|
const tagRender = ({
|
||||||
|
label,
|
||||||
|
value,
|
||||||
|
closable,
|
||||||
|
disabled,
|
||||||
|
onClose,
|
||||||
|
}: HavingTagRenderProps): JSX.Element => {
|
||||||
|
const handleClose = (): void => {
|
||||||
|
onClose();
|
||||||
|
setSearchText('');
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<HavingFilterTag
|
||||||
|
label={label}
|
||||||
|
value={value}
|
||||||
|
closable={closable}
|
||||||
|
disabled={disabled}
|
||||||
|
onClose={handleClose}
|
||||||
|
onUpdate={handleUpdateTag}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearch = (search: string): void => {
|
||||||
|
const trimmedSearch = search.replace(/\s\s+/g, ' ').trimStart();
|
||||||
|
|
||||||
|
const currentSearch = isMulti
|
||||||
|
? trimmedSearch
|
||||||
|
: trimmedSearch.split(' ').slice(0, 3).join(' ');
|
||||||
|
|
||||||
|
const isValidSearch = isValidHavingValue(currentSearch);
|
||||||
|
|
||||||
|
if (isValidSearch) {
|
||||||
|
setSearchText(currentSearch);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setLocalValues(transformHavingToStringValue(having || []));
|
||||||
|
}, [having]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
parseSearchText(searchText);
|
||||||
|
}, [searchText, parseSearchText]);
|
||||||
|
|
||||||
|
const resetChanges = (): void => {
|
||||||
|
setSearchText('');
|
||||||
|
setCurrentFormValue(initialHavingValues);
|
||||||
|
setOptions(aggregatorOptions);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDeselect = (value: string): void => {
|
||||||
|
const result = localValues.filter((item) => item !== value);
|
||||||
|
const having: Having[] = result.map(transformFromStringToHaving);
|
||||||
|
onChange(having);
|
||||||
|
resetChanges();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelect = (currentValue: string): void => {
|
||||||
|
const { columnName, op, value } = getHavingObject(currentValue);
|
||||||
|
|
||||||
|
const isCompletedValue = value.every((item) => !!item);
|
||||||
|
|
||||||
|
const isClearSearch = isCompletedValue && columnName && op;
|
||||||
|
|
||||||
|
setSearchText(isClearSearch ? '' : currentValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChange = (values: string[]): void => {
|
||||||
|
const having: Having[] = values.map(transformFromStringToHaving);
|
||||||
|
|
||||||
|
const isSelectable =
|
||||||
|
currentFormValue.value.length > 0 &&
|
||||||
|
currentFormValue.value.every((value) => !!value);
|
||||||
|
|
||||||
|
if (isSelectable) {
|
||||||
|
onChange(having);
|
||||||
|
resetChanges();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
|
autoClearSearchValue={false}
|
||||||
|
mode="multiple"
|
||||||
|
onSearch={handleSearch}
|
||||||
|
searchValue={searchText}
|
||||||
|
data-testid="havingSelectFormula"
|
||||||
|
placeholder="Count(operation) > 5"
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
tagRender={tagRender}
|
||||||
|
onDeselect={handleDeselect}
|
||||||
|
onSelect={handleSelect}
|
||||||
|
onChange={handleChange}
|
||||||
|
value={localValues}
|
||||||
|
>
|
||||||
|
{options.map((opt) => (
|
||||||
|
<Select.Option key={opt.value} value={opt.value} title="havingOption">
|
||||||
|
{opt.label}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HavingFilter;
|
@ -0,0 +1,12 @@
|
|||||||
|
import { HavingFilterTagProps } from 'container/QueryBuilder/components/HavingFilterTag/HavingFilterTag.interfaces';
|
||||||
|
import {
|
||||||
|
Having,
|
||||||
|
IBuilderFormula,
|
||||||
|
} from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
|
export type HavingFilterProps = {
|
||||||
|
formula: IBuilderFormula;
|
||||||
|
onChange: (having: Having[]) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type HavingTagRenderProps = Omit<HavingFilterTagProps, 'onUpdate'>;
|
@ -0,0 +1,20 @@
|
|||||||
|
import { InputNumber } from 'antd';
|
||||||
|
|
||||||
|
import { selectStyle } from '../../QueryBuilderSearch/config';
|
||||||
|
import { handleKeyDownLimitFilter } from '../../utils';
|
||||||
|
import { LimitFilterProps } from './types';
|
||||||
|
|
||||||
|
function LimitFilter({ onChange, formula }: LimitFilterProps): JSX.Element {
|
||||||
|
return (
|
||||||
|
<InputNumber
|
||||||
|
min={1}
|
||||||
|
type="number"
|
||||||
|
value={formula.limit}
|
||||||
|
style={selectStyle}
|
||||||
|
onChange={onChange}
|
||||||
|
onKeyDown={handleKeyDownLimitFilter}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LimitFilter;
|
@ -0,0 +1,6 @@
|
|||||||
|
import { IBuilderFormula } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
|
export interface LimitFilterProps {
|
||||||
|
onChange: (values: number | null) => void;
|
||||||
|
formula: IBuilderFormula;
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
import { Select, Spin } from 'antd';
|
||||||
|
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { MetricAggregateOperator } from 'types/common/queryBuilder';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
|
import { selectStyle } from '../../QueryBuilderSearch/config';
|
||||||
|
import { OrderByProps } from './types';
|
||||||
|
import { useOrderByFormulaFilter } from './useOrderByFormulaFilter';
|
||||||
|
|
||||||
|
function OrderByFilter({
|
||||||
|
formula,
|
||||||
|
onChange,
|
||||||
|
query,
|
||||||
|
}: OrderByProps): JSX.Element {
|
||||||
|
const {
|
||||||
|
debouncedSearchText,
|
||||||
|
createOptions,
|
||||||
|
aggregationOptions,
|
||||||
|
handleChange,
|
||||||
|
handleSearchKeys,
|
||||||
|
selectedValue,
|
||||||
|
generateOptions,
|
||||||
|
} = useOrderByFormulaFilter({
|
||||||
|
query,
|
||||||
|
onChange,
|
||||||
|
formula,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { data, isFetching } = useGetAggregateKeys(
|
||||||
|
{
|
||||||
|
aggregateAttribute: query.aggregateAttribute.key,
|
||||||
|
dataSource: query.dataSource,
|
||||||
|
aggregateOperator: query.aggregateOperator,
|
||||||
|
searchText: debouncedSearchText,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!query.aggregateAttribute.key,
|
||||||
|
keepPreviousData: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const optionsData = useMemo(() => {
|
||||||
|
const keyOptions = createOptions(data?.payload?.attributeKeys || []);
|
||||||
|
const groupByOptions = createOptions(query.groupBy);
|
||||||
|
const options =
|
||||||
|
query.aggregateOperator === MetricAggregateOperator.NOOP
|
||||||
|
? keyOptions
|
||||||
|
: [...groupByOptions, ...aggregationOptions];
|
||||||
|
|
||||||
|
return generateOptions(options);
|
||||||
|
}, [
|
||||||
|
aggregationOptions,
|
||||||
|
createOptions,
|
||||||
|
data?.payload?.attributeKeys,
|
||||||
|
generateOptions,
|
||||||
|
query.aggregateOperator,
|
||||||
|
query.groupBy,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const isDisabledSelect =
|
||||||
|
!query.aggregateAttribute.key ||
|
||||||
|
query.aggregateOperator === MetricAggregateOperator.NOOP;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
|
mode="tags"
|
||||||
|
style={selectStyle}
|
||||||
|
onSearch={handleSearchKeys}
|
||||||
|
showSearch
|
||||||
|
disabled={isDisabledSelect}
|
||||||
|
showArrow={false}
|
||||||
|
value={selectedValue}
|
||||||
|
labelInValue
|
||||||
|
filterOption={false}
|
||||||
|
options={optionsData}
|
||||||
|
notFoundContent={isFetching ? <Spin size="small" /> : null}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default OrderByFilter;
|
@ -0,0 +1,12 @@
|
|||||||
|
import {
|
||||||
|
IBuilderFormula,
|
||||||
|
IBuilderQuery,
|
||||||
|
} from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
|
export interface OrderByProps {
|
||||||
|
formula: IBuilderFormula;
|
||||||
|
query: IBuilderQuery;
|
||||||
|
onChange: (value: IBuilderFormula['orderBy']) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IOrderByFormulaFilterProps = OrderByProps;
|
@ -0,0 +1,127 @@
|
|||||||
|
import { DEBOUNCE_DELAY } from 'constants/queryBuilderFilterConfig';
|
||||||
|
import useDebounce from 'hooks/useDebounce';
|
||||||
|
import { IOption } from 'hooks/useResourceAttribute/types';
|
||||||
|
import isEqual from 'lodash-es/isEqual';
|
||||||
|
import uniqWith from 'lodash-es/uniqWith';
|
||||||
|
import { parse } from 'papaparse';
|
||||||
|
import { useMemo, useState } from 'react';
|
||||||
|
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
|
import { OrderByPayload } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
|
import { ORDERBY_FILTERS } from '../../OrderByFilter/config';
|
||||||
|
import { SIGNOZ_VALUE } from '../../OrderByFilter/constants';
|
||||||
|
import { UseOrderByFilterResult } from '../../OrderByFilter/useOrderByFilter';
|
||||||
|
import {
|
||||||
|
getLabelFromValue,
|
||||||
|
mapLabelValuePairs,
|
||||||
|
orderByValueDelimiter,
|
||||||
|
} from '../../OrderByFilter/utils';
|
||||||
|
import { getRemoveOrderFromValue } from '../../QueryBuilderSearch/utils';
|
||||||
|
import { getUniqueOrderByValues, getValidOrderByResult } from '../../utils';
|
||||||
|
import { IOrderByFormulaFilterProps } from './types';
|
||||||
|
import { transformToOrderByStringValuesByFormula } from './utils';
|
||||||
|
|
||||||
|
export const useOrderByFormulaFilter = ({
|
||||||
|
onChange,
|
||||||
|
formula,
|
||||||
|
}: IOrderByFormulaFilterProps): UseOrderByFilterResult => {
|
||||||
|
const [searchText, setSearchText] = useState<string>('');
|
||||||
|
|
||||||
|
const debouncedSearchText = useDebounce(searchText, DEBOUNCE_DELAY);
|
||||||
|
|
||||||
|
const handleSearchKeys = (searchText: string): void =>
|
||||||
|
setSearchText(searchText);
|
||||||
|
|
||||||
|
const handleChange = (values: IOption[]): void => {
|
||||||
|
const validResult = getValidOrderByResult(values);
|
||||||
|
const result = getUniqueOrderByValues(validResult);
|
||||||
|
|
||||||
|
const orderByValues: OrderByPayload[] = result.map((item) => {
|
||||||
|
const match = parse(item.value, { delimiter: orderByValueDelimiter });
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
return {
|
||||||
|
columnName: item.value,
|
||||||
|
order: ORDERBY_FILTERS.ASC,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const [columnName, order] = match.data.flat() as string[];
|
||||||
|
|
||||||
|
const columnNameValue =
|
||||||
|
columnName === SIGNOZ_VALUE ? SIGNOZ_VALUE : columnName;
|
||||||
|
|
||||||
|
const orderValue = order ?? ORDERBY_FILTERS.ASC;
|
||||||
|
|
||||||
|
return {
|
||||||
|
columnName: columnNameValue,
|
||||||
|
order: orderValue,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
setSearchText('');
|
||||||
|
onChange(orderByValues);
|
||||||
|
};
|
||||||
|
|
||||||
|
const aggregationOptions = [
|
||||||
|
{
|
||||||
|
label: `${formula.expression} ${ORDERBY_FILTERS.ASC}`,
|
||||||
|
value: `${SIGNOZ_VALUE}${orderByValueDelimiter}${ORDERBY_FILTERS.ASC}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: `${formula.expression} ${ORDERBY_FILTERS.DESC}`,
|
||||||
|
value: `${SIGNOZ_VALUE}${orderByValueDelimiter}${ORDERBY_FILTERS.DESC}`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const selectedValue = transformToOrderByStringValuesByFormula(formula);
|
||||||
|
|
||||||
|
const createOptions = (data: BaseAutocompleteData[]): IOption[] =>
|
||||||
|
mapLabelValuePairs(data).flat();
|
||||||
|
|
||||||
|
const customValue: IOption[] = useMemo(() => {
|
||||||
|
if (!searchText) return [];
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: `${searchText} ${ORDERBY_FILTERS.ASC}`,
|
||||||
|
value: `${searchText}${orderByValueDelimiter}${ORDERBY_FILTERS.ASC}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: `${searchText} ${ORDERBY_FILTERS.DESC}`,
|
||||||
|
value: `${searchText}${orderByValueDelimiter}${ORDERBY_FILTERS.DESC}`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}, [searchText]);
|
||||||
|
|
||||||
|
const generateOptions = (options: IOption[]): IOption[] => {
|
||||||
|
const currentCustomValue = options.find(
|
||||||
|
(keyOption) =>
|
||||||
|
getRemoveOrderFromValue(keyOption.value) === debouncedSearchText,
|
||||||
|
)
|
||||||
|
? []
|
||||||
|
: customValue;
|
||||||
|
|
||||||
|
const result = [...currentCustomValue, ...options];
|
||||||
|
|
||||||
|
const uniqResult = uniqWith(result, isEqual);
|
||||||
|
|
||||||
|
return uniqResult.filter(
|
||||||
|
(option) =>
|
||||||
|
!getLabelFromValue(selectedValue).includes(
|
||||||
|
getRemoveOrderFromValue(option.value),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
searchText,
|
||||||
|
debouncedSearchText,
|
||||||
|
selectedValue,
|
||||||
|
aggregationOptions,
|
||||||
|
createOptions,
|
||||||
|
handleChange,
|
||||||
|
handleSearchKeys,
|
||||||
|
generateOptions,
|
||||||
|
};
|
||||||
|
};
|
@ -0,0 +1,26 @@
|
|||||||
|
import { IOption } from 'hooks/useResourceAttribute/types';
|
||||||
|
import { IBuilderFormula } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
|
import { SIGNOZ_VALUE } from '../../OrderByFilter/constants';
|
||||||
|
import { orderByValueDelimiter } from '../../OrderByFilter/utils';
|
||||||
|
|
||||||
|
export const transformToOrderByStringValuesByFormula = (
|
||||||
|
formula: IBuilderFormula,
|
||||||
|
): IOption[] => {
|
||||||
|
const prepareSelectedValue: IOption[] =
|
||||||
|
formula?.orderBy?.map((item) => {
|
||||||
|
if (item.columnName === SIGNOZ_VALUE) {
|
||||||
|
return {
|
||||||
|
label: `${formula.expression} ${item.order}`,
|
||||||
|
value: `${item.columnName}${orderByValueDelimiter}${item.order}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
label: `${item.columnName} ${item.order}`,
|
||||||
|
value: `${item.columnName}${orderByValueDelimiter}${item.order}`,
|
||||||
|
};
|
||||||
|
}) || [];
|
||||||
|
|
||||||
|
return prepareSelectedValue;
|
||||||
|
};
|
@ -18,6 +18,7 @@ import { memo, useCallback, useEffect, useState } from 'react';
|
|||||||
import { useQueryClient } from 'react-query';
|
import { useQueryClient } from 'react-query';
|
||||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
import { SelectOption } from 'types/common/select';
|
import { SelectOption } from 'types/common/select';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
import { selectStyle } from '../QueryBuilderSearch/config';
|
import { selectStyle } from '../QueryBuilderSearch/config';
|
||||||
import { GroupByFilterProps } from './GroupByFilter.interfaces';
|
import { GroupByFilterProps } from './GroupByFilter.interfaces';
|
||||||
@ -169,6 +170,7 @@ export const GroupByFilter = memo(function GroupByFilter({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
mode="tags"
|
mode="tags"
|
||||||
style={selectStyle}
|
style={selectStyle}
|
||||||
onSearch={handleSearchKeys}
|
onSearch={handleSearchKeys}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Select } from 'antd';
|
import { Select } from 'antd';
|
||||||
// ** Constants
|
// ** Constants
|
||||||
import { HAVING_OPERATORS, initialHavingValues } from 'constants/queryBuilder';
|
import { HAVING_OPERATORS, initialHavingValues } from 'constants/queryBuilder';
|
||||||
import { HAVING_FILTER_REGEXP } from 'constants/regExp';
|
|
||||||
import { HavingFilterTag } from 'container/QueryBuilder/components';
|
import { HavingFilterTag } from 'container/QueryBuilder/components';
|
||||||
import { HavingTagRenderProps } from 'container/QueryBuilder/components/HavingFilterTag/HavingFilterTag.interfaces';
|
import { HavingTagRenderProps } from 'container/QueryBuilder/components/HavingFilterTag/HavingFilterTag.interfaces';
|
||||||
// ** Hooks
|
// ** Hooks
|
||||||
@ -16,12 +15,12 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
|||||||
import { Having, HavingForm } from 'types/api/queryBuilder/queryBuilderData';
|
import { Having, HavingForm } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
import { SelectOption } from 'types/common/select';
|
import { SelectOption } from 'types/common/select';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
|
||||||
|
import { getHavingObject, isValidHavingValue } from '../utils';
|
||||||
// ** Types
|
// ** Types
|
||||||
import { HavingFilterProps } from './HavingFilter.interfaces';
|
import { HavingFilterProps } from './HavingFilter.interfaces';
|
||||||
|
|
||||||
const { Option } = Select;
|
|
||||||
|
|
||||||
export function HavingFilter({
|
export function HavingFilter({
|
||||||
query,
|
query,
|
||||||
onChange,
|
onChange,
|
||||||
@ -59,13 +58,6 @@ export function HavingFilter({
|
|||||||
[columnName],
|
[columnName],
|
||||||
);
|
);
|
||||||
|
|
||||||
const getHavingObject = useCallback((currentSearch: string): HavingForm => {
|
|
||||||
const textArr = currentSearch.split(' ');
|
|
||||||
const [columnName = '', op = '', ...value] = textArr;
|
|
||||||
|
|
||||||
return { columnName, op, value };
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const generateOptions = useCallback(
|
const generateOptions = useCallback(
|
||||||
(search: string): void => {
|
(search: string): void => {
|
||||||
const [aggregator = '', op = '', ...restValue] = search.split(' ');
|
const [aggregator = '', op = '', ...restValue] = search.split(' ');
|
||||||
@ -97,19 +89,6 @@ export function HavingFilter({
|
|||||||
[columnName, aggregatorOptions],
|
[columnName, aggregatorOptions],
|
||||||
);
|
);
|
||||||
|
|
||||||
const isValidHavingValue = useCallback(
|
|
||||||
(search: string): boolean => {
|
|
||||||
const values = getHavingObject(search).value.join(' ');
|
|
||||||
|
|
||||||
if (values) {
|
|
||||||
return HAVING_FILTER_REGEXP.test(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
[getHavingObject],
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleSearch = useCallback(
|
const handleSearch = useCallback(
|
||||||
(search: string): void => {
|
(search: string): void => {
|
||||||
const trimmedSearch = search.replace(/\s\s+/g, ' ').trimStart();
|
const trimmedSearch = search.replace(/\s\s+/g, ' ').trimStart();
|
||||||
@ -124,7 +103,7 @@ export function HavingFilter({
|
|||||||
setSearchText(currentSearch);
|
setSearchText(currentSearch);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[isMulti, isValidHavingValue],
|
[isMulti],
|
||||||
);
|
);
|
||||||
|
|
||||||
const resetChanges = useCallback((): void => {
|
const resetChanges = useCallback((): void => {
|
||||||
@ -199,7 +178,7 @@ export function HavingFilter({
|
|||||||
|
|
||||||
generateOptions(text);
|
generateOptions(text);
|
||||||
},
|
},
|
||||||
[generateOptions, getHavingObject],
|
[generateOptions],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleDeselect = (value: string): void => {
|
const handleDeselect = (value: string): void => {
|
||||||
@ -217,13 +196,11 @@ export function HavingFilter({
|
|||||||
setLocalValues(transformHavingToStringValue(having));
|
setLocalValues(transformHavingToStringValue(having));
|
||||||
}, [having]);
|
}, [having]);
|
||||||
|
|
||||||
const isMetricsDataSource = useMemo(
|
const isMetricsDataSource = query.dataSource === DataSource.METRICS;
|
||||||
() => query.dataSource === DataSource.METRICS,
|
|
||||||
[query.dataSource],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
autoClearSearchValue={false}
|
autoClearSearchValue={false}
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
onSearch={handleSearch}
|
onSearch={handleSearch}
|
||||||
@ -240,9 +217,9 @@ export function HavingFilter({
|
|||||||
onSelect={handleSelect}
|
onSelect={handleSelect}
|
||||||
>
|
>
|
||||||
{options.map((opt) => (
|
{options.map((opt) => (
|
||||||
<Option key={opt.value} value={opt.value} title="havingOption">
|
<Select.Option key={opt.value} value={opt.value} title="havingOption">
|
||||||
{opt.label}
|
{opt.label}
|
||||||
</Option>
|
</Select.Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
);
|
);
|
||||||
|
@ -1,30 +1,12 @@
|
|||||||
import { InputNumber } from 'antd';
|
import { InputNumber } from 'antd';
|
||||||
import { useMemo } from 'react';
|
|
||||||
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
|
|
||||||
import { selectStyle } from '../QueryBuilderSearch/config';
|
import { selectStyle } from '../QueryBuilderSearch/config';
|
||||||
|
import { handleKeyDownLimitFilter } from '../utils';
|
||||||
|
|
||||||
function LimitFilter({ onChange, query }: LimitFilterProps): JSX.Element {
|
function LimitFilter({ onChange, query }: LimitFilterProps): JSX.Element {
|
||||||
const handleKeyDown = (event: {
|
const isMetricsDataSource = query.dataSource === DataSource.METRICS;
|
||||||
keyCode: number;
|
|
||||||
which: number;
|
|
||||||
preventDefault: () => void;
|
|
||||||
}): void => {
|
|
||||||
const keyCode = event.keyCode || event.which;
|
|
||||||
const isBackspace = keyCode === 8;
|
|
||||||
const isNumeric =
|
|
||||||
(keyCode >= 48 && keyCode <= 57) || (keyCode >= 96 && keyCode <= 105);
|
|
||||||
|
|
||||||
if (!isNumeric && !isBackspace) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const isMetricsDataSource = useMemo(
|
|
||||||
() => query.dataSource === DataSource.METRICS,
|
|
||||||
[query.dataSource],
|
|
||||||
);
|
|
||||||
|
|
||||||
const isDisabled = isMetricsDataSource && !query.aggregateAttribute.key;
|
const isDisabled = isMetricsDataSource && !query.aggregateAttribute.key;
|
||||||
|
|
||||||
@ -36,7 +18,7 @@ function LimitFilter({ onChange, query }: LimitFilterProps): JSX.Element {
|
|||||||
style={selectStyle}
|
style={selectStyle}
|
||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDownLimitFilter}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,9 @@ export type OrderByFilterProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type OrderByFilterValue = {
|
export type OrderByFilterValue = {
|
||||||
disabled: boolean | undefined;
|
disabled?: boolean;
|
||||||
key: string;
|
key: string;
|
||||||
label: string;
|
label: string;
|
||||||
title: string | undefined;
|
title?: string;
|
||||||
value: string;
|
value: string;
|
||||||
};
|
};
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user