Skip to content

Commit dbab46b

Browse files
authored
feat: add database hyperlink to logging service (#2021)
1 parent 7aacdfe commit dbab46b

File tree

10 files changed

+95
-19
lines changed

10 files changed

+95
-19
lines changed
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {FileText} from '@gravity-ui/icons';
2+
import type {ButtonSize} from '@gravity-ui/uikit';
3+
import {Button, Icon} from '@gravity-ui/uikit';
4+
5+
interface LogsButtonProps {
6+
className?: string;
7+
href: string;
8+
size?: ButtonSize;
9+
}
10+
11+
export function LogsButton({href, className, size = 'xs'}: LogsButtonProps) {
12+
return (
13+
<Button href={href} target="_blank" className={className} size={size} title="Database logs">
14+
<Icon data={FileText} />
15+
</Button>
16+
);
17+
}

src/components/TenantNameWrapper/TenantNameWrapper.tsx

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {DefinitionList, PopoverBehavior} from '@gravity-ui/uikit';
1+
import {DefinitionList, Flex, PopoverBehavior} from '@gravity-ui/uikit';
22

33
import {getTenantPath} from '../../containers/Tenant/TenantPages';
44
import type {PreparedTenant} from '../../store/reducers/tenants/types';
@@ -39,19 +39,27 @@ export function TenantNameWrapper({tenant, additionalTenantsProps}: TenantNameWr
3939
const isExternalLink = Boolean(backend);
4040

4141
const monitoringLink = additionalTenantsProps?.getMonitoringLink?.(tenant.Name, tenant.Type);
42+
const logsLink = additionalTenantsProps?.getLogsLink?.(tenant.Name);
4243

4344
return (
4445
<CellWithPopover
45-
disabled={!isUserAllowedToMakeChanges || !monitoringLink}
46+
disabled={!isUserAllowedToMakeChanges || (!monitoringLink && !logsLink)}
4647
delayClosing={200}
4748
content={
48-
monitoringLink ? (
49+
monitoringLink || logsLink ? (
4950
<DefinitionList responsive>
5051
<DefinitionList.Item name={i18n('field_links')}>
51-
<LinkWithIcon
52-
title={i18n('field_monitoring-link')}
53-
url={monitoringLink}
54-
/>
52+
<Flex gap={2} wrap="wrap">
53+
{monitoringLink && (
54+
<LinkWithIcon
55+
title={i18n('field_monitoring-link')}
56+
url={monitoringLink}
57+
/>
58+
)}
59+
{logsLink && (
60+
<LinkWithIcon title={i18n('field_logs-link')} url={logsLink} />
61+
)}
62+
</Flex>
5563
</DefinitionList.Item>
5664
</DefinitionList>
5765
) : null
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"field_links": "Links",
33
"field_monitoring-link": "Monitoring",
4+
"field_logs-link": "Logs",
45
"context_unknown": "unknown database"
56
}

src/containers/AppWithClusters/AppWithClusters.tsx

+9-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import React from 'react';
33
import type {Store} from '@reduxjs/toolkit';
44
import type {History} from 'history';
55

6-
import type {GetMonitoringClusterLink, GetMonitoringLink} from '../../utils/monitoring';
6+
import type {
7+
GetLogsLink,
8+
GetMonitoringClusterLink,
9+
GetMonitoringLink,
10+
} from '../../utils/monitoring';
711
import {
812
getMonitoringClusterLink as getMonitoringClusterLinkDefault,
913
getMonitoringLink as getMonitoringLinkDefault,
@@ -17,6 +21,7 @@ import {ExtendedTenant} from './ExtendedTenant/ExtendedTenant';
1721
export interface AppWithClustersProps {
1822
store: Store;
1923
history: History;
24+
getLogsLink?: GetLogsLink;
2025
getMonitoringLink?: GetMonitoringLink;
2126
getMonitoringClusterLink?: GetMonitoringClusterLink;
2227
userSettings?: YDBEmbeddedUISettings;
@@ -26,6 +31,7 @@ export interface AppWithClustersProps {
2631
export function AppWithClusters({
2732
store,
2833
history,
34+
getLogsLink,
2935
getMonitoringLink = getMonitoringLinkDefault,
3036
getMonitoringClusterLink = getMonitoringClusterLinkDefault,
3137
userSettings,
@@ -38,6 +44,7 @@ export function AppWithClusters({
3844
return (
3945
<ExtendedCluster
4046
component={component}
47+
getLogsLink={getLogsLink}
4148
getMonitoringLink={getMonitoringLink}
4249
getMonitoringClusterLink={getMonitoringClusterLink}
4350
/>
@@ -49,6 +56,7 @@ export function AppWithClusters({
4956
return (
5057
<ExtendedTenant
5158
component={component}
59+
getLogsLink={getLogsLink}
5260
getMonitoringLink={getMonitoringLink}
5361
/>
5462
);

src/containers/AppWithClusters/ExtendedCluster/ExtendedCluster.tsx

+22-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ import {cn} from '../../../utils/cn';
1111
import {USE_CLUSTER_BALANCER_AS_BACKEND_KEY} from '../../../utils/constants';
1212
import {useSetting} from '../../../utils/hooks';
1313
import {useAdditionalNodesProps} from '../../../utils/hooks/useAdditionalNodesProps';
14-
import type {GetMonitoringClusterLink, GetMonitoringLink} from '../../../utils/monitoring';
14+
import type {
15+
GetLogsLink,
16+
GetMonitoringClusterLink,
17+
GetMonitoringLink,
18+
} from '../../../utils/monitoring';
1519
import {getCleanBalancerValue, removeViewerPathname} from '../../../utils/parseBalancer';
1620
import {getBackendFromNodeHost, getBackendFromRawNodeData} from '../../../utils/prepareBackend';
1721
import type {Cluster} from '../../Cluster/Cluster';
@@ -63,6 +67,7 @@ const getAdditionalTenantsProps = (
6367
balancer: string | undefined,
6468
useClusterBalancerAsBackend: boolean | undefined,
6569
getMonitoringLink?: GetMonitoringLink,
70+
getLogsLink?: GetLogsLink,
6671
) => {
6772
const additionalTenantsProps: AdditionalTenantsProps = {};
6873

@@ -99,18 +104,33 @@ const getAdditionalTenantsProps = (
99104
};
100105
}
101106

107+
if (clusterName && getLogsLink) {
108+
additionalTenantsProps.getLogsLink = (dbName?: string) => {
109+
if (dbName) {
110+
return getLogsLink({
111+
dbName,
112+
clusterName,
113+
});
114+
}
115+
116+
return null;
117+
};
118+
}
119+
102120
return additionalTenantsProps;
103121
};
104122

105123
interface ExtendedClusterProps {
106124
component: typeof Cluster;
107125
getMonitoringLink?: GetMonitoringLink;
108126
getMonitoringClusterLink?: GetMonitoringClusterLink;
127+
getLogsLink?: GetLogsLink;
109128
}
110129
export function ExtendedCluster({
111130
component: ClusterComponent,
112131
getMonitoringLink,
113132
getMonitoringClusterLink,
133+
getLogsLink,
114134
}: ExtendedClusterProps) {
115135
const additionalNodesProps = useAdditionalNodesProps();
116136
const {name, balancer, monitoring} = useClusterBaseInfo();
@@ -132,6 +152,7 @@ export function ExtendedCluster({
132152
balancer,
133153
useClusterBalancerAsBackend,
134154
getMonitoringLink,
155+
getLogsLink,
135156
)}
136157
additionalNodesProps={additionalNodesProps}
137158
/>

src/containers/AppWithClusters/ExtendedTenant/ExtendedTenant.tsx

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
import {useClusterBaseInfo} from '../../../store/reducers/cluster/cluster';
22
import type {ETenantType} from '../../../types/api/tenant';
33
import {useAdditionalNodesProps} from '../../../utils/hooks/useAdditionalNodesProps';
4-
import type {GetMonitoringLink} from '../../../utils/monitoring';
4+
import type {GetLogsLink, GetMonitoringLink} from '../../../utils/monitoring';
55
import type {Tenant} from '../../Tenant/Tenant';
66

77
export interface ExtendedTenantProps {
88
component: typeof Tenant;
99
getMonitoringLink?: GetMonitoringLink;
10+
getLogsLink?: GetLogsLink;
1011
}
1112

1213
export function ExtendedTenant({
1314
component: TenantComponent,
1415
getMonitoringLink,
16+
getLogsLink,
1517
}: ExtendedTenantProps) {
16-
const {monitoring} = useClusterBaseInfo();
18+
const {monitoring, name: clusterName} = useClusterBaseInfo();
1719
const additionalNodesProps = useAdditionalNodesProps();
1820

1921
const additionalTenantProps = {
@@ -26,6 +28,16 @@ export function ExtendedTenant({
2628
});
2729
}
2830

31+
return null;
32+
},
33+
getLogsLink: (dbName?: string) => {
34+
if (clusterName && dbName && getLogsLink) {
35+
return getLogsLink({
36+
dbName,
37+
clusterName,
38+
});
39+
}
40+
2941
return null;
3042
},
3143
};

src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.scss

-4
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@
1717
}
1818

1919
&__top {
20-
display: flex;
21-
align-items: center;
22-
gap: 4px;
23-
2420
margin-bottom: 10px;
2521

2622
line-height: 24px;

src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import {Loader} from '@gravity-ui/uikit';
1+
import {Flex, Loader} from '@gravity-ui/uikit';
22

33
import {EntityStatus} from '../../../../components/EntityStatus/EntityStatus';
4+
import {LogsButton} from '../../../../components/LogsButton/LogsButton';
45
import {MonitoringButton} from '../../../../components/MonitoringButton/MonitoringButton';
56
import {overviewApi} from '../../../../store/reducers/overview/overview';
67
import {TENANT_METRICS_TABS_IDS} from '../../../../store/reducers/tenant/constants';
@@ -150,15 +151,19 @@ export function TenantOverview({
150151
}
151152

152153
const monitoringLink = additionalTenantProps?.getMonitoringLink?.(Name, Type);
154+
const logsLink = additionalTenantProps?.getLogsLink?.(Name);
153155

154156
return (
155157
<div className={b()}>
156158
<div className={b('info')}>
157159
<div className={b('top-label')}>{tenantType}</div>
158-
<div className={b('top')}>
160+
<Flex alignItems="center" gap="1" className={b('top')}>
159161
{renderName()}
160-
{monitoringLink && <MonitoringButton href={monitoringLink} />}
161-
</div>
162+
<Flex gap="2">
163+
{monitoringLink && <MonitoringButton href={monitoringLink} />}
164+
{logsLink && <LogsButton href={logsLink} />}
165+
</Flex>
166+
</Flex>
162167
<MetricsCards
163168
poolsCpuStats={poolsStats}
164169
memoryStats={memoryStats}

src/types/additionalProps.ts

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface AdditionalClusterProps {
1515
export interface AdditionalTenantsProps {
1616
prepareTenantBackend?: (backend: string | NodeAddress | undefined) => string | undefined;
1717
getMonitoringLink?: (name?: string, type?: ETenantType) => string | null;
18+
getLogsLink?: (name?: string) => string | null;
1819
}
1920

2021
export type NodeAddress = Pick<TSystemStateInfo, 'Host' | 'Endpoints' | 'NodeId'>;

src/utils/monitoring.ts

+7
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,10 @@ export function parseMonitoringData(monitoring: string): ParsedMonitoringData |
9999

100100
return undefined;
101101
}
102+
103+
interface GetLogsLinkProps {
104+
dbName: string;
105+
clusterName: string;
106+
}
107+
108+
export type GetLogsLink = (props: GetLogsLinkProps) => string;

0 commit comments

Comments
 (0)