Skip to content

Commit

Permalink
[vtadmin-web] The hastiest Tablet view (+ experimental debug vars)
Browse files Browse the repository at this point in the history
Signed-off-by: Sara Bee <855595+doeg@users.noreply.github.com>
  • Loading branch information
doeg committed May 21, 2021
1 parent 1d2e0c9 commit 3d45c22
Show file tree
Hide file tree
Showing 12 changed files with 316 additions and 15 deletions.
5 changes: 3 additions & 2 deletions examples/local/scripts/vtadmin-up.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ vtadmin_api_port=14200
vtadmin \
--addr ":${vtadmin_api_port}" \
--http-origin "http://localhost:3000" \
--http-tablet-url-tmpl "http://localhost:15{{ .Tablet.Alias.Uid }}" \
--http-tablet-url-tmpl "http://{{ .Tablet.Hostname }}:15{{ .Tablet.Alias.Uid }}" \
--tracer "opentracing-jaeger" \
--grpc-tracing \
--http-tracing \
--logtostderr \
--alsologtostderr \
--cluster "id=local,name=local,discovery=staticfile,discovery-staticfile-path=./vtadmin/discovery.json,tablet-fqdn-tmpl=localhost:15{{ .Tablet.Alias.Uid }}" \
--cluster "id=local,name=local,discovery=staticfile,discovery-staticfile-path=./vtadmin/discovery.json,tablet-fqdn-tmpl={{ .Tablet.Hostname }}:15{{ .Tablet.Alias.Uid }}" \
> "${log_dir}/vtadmin-api.out" 2>&1 &
vtadmin_pid=$!

Expand All @@ -33,5 +33,6 @@ echo "vtadmin-api is running on http://localhost:${vtadmin_api_port}. Logs are i
cd ../../web/vtadmin &&
npm install &&
REACT_APP_VTADMIN_API_ADDRESS="http://127.0.0.1:${vtadmin_api_port}" \
REACT_APP_ENABLE_EXPERIMENTAL_TABLET_DEBUG_VARS="true" \
npm run start
)
24 changes: 23 additions & 1 deletion web/vtadmin/src/api/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,29 @@ export const fetchSchema = async ({ clusterID, keyspace, table }: FetchSchemaPar
return pb.Schema.create(result);
};

export interface FetchTabletParams {
clusterID: string;
alias: string;
}

export const fetchTablet = async ({ clusterID, alias }: FetchTabletParams) => {
const { result } = await vtfetch(`/api/tablet/${alias}?cluster=${clusterID}`);

const err = pb.Tablet.verify(result);
if (err) throw Error(err);

return pb.Tablet.create(result);
};

export const fetchExperimentalTabletDebugVars = async ({ clusterID, alias }: FetchTabletParams) => {
if (!process.env.REACT_APP_ENABLE_EXPERIMENTAL_TABLET_DEBUG_VARS) {
return Promise.resolve({});
}

const { result } = await vtfetch(`/api/experimental/tablet/${alias}/debug/vars?cluster=${clusterID}`);
return result;
};

export const fetchTablets = async () =>
vtfetchEntities({
endpoint: '/api/tablets',
Expand All @@ -181,7 +204,6 @@ export const fetchTablets = async () =>
return pb.Tablet.create(e);
},
});

export interface FetchVSchemaParams {
clusterID: string;
keyspace: string;
Expand Down
5 changes: 5 additions & 0 deletions web/vtadmin/src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { Workflows } from './routes/Workflows';
import { Workflow } from './routes/Workflow';
import { VTExplain } from './routes/VTExplain';
import { Keyspace } from './routes/keyspace/Keyspace';
import { Tablet } from './routes/tablet/Tablet';

export const App = () => {
return (
Expand Down Expand Up @@ -70,6 +71,10 @@ export const App = () => {
<Tablets />
</Route>

<Route path="/tablet/:clusterID/:alias">
<Tablet />
</Route>

<Route path="/vtexplain">
<VTExplain />
</Route>
Expand Down
32 changes: 32 additions & 0 deletions web/vtadmin/src/components/links/ExternalTabletLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright 2021 The Vitess Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

interface Props {
className?: string;
fqdn?: string | null | undefined;
}

export const ExternalTabletLink: React.FunctionComponent<Props> = ({ children, className, fqdn }) => {
if (!fqdn) {
return <span className={className}>{children}</span>;
}

return (
<a className={className} href={`//${fqdn}`} rel="noreferrer" target="_blank">
{children}
</a>
);
};
37 changes: 37 additions & 0 deletions web/vtadmin/src/components/links/TabletLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright 2021 The Vitess Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { Link } from 'react-router-dom';

interface Props {
alias: string | null | undefined;
className?: string;
clusterID: string | null | undefined;
}

export const TabletLink: React.FunctionComponent<Props> = ({ alias, children, className, clusterID }) => {
if (!clusterID || !alias) {
return <span className={className}>{children}</span>;
}

const to = { pathname: `/tablet/${clusterID}/${alias}` };

return (
<Link className={className} to={to}>
{children}
</Link>
);
};
22 changes: 16 additions & 6 deletions web/vtadmin/src/components/routes/Tablets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import { WorkspaceHeader } from '../layout/WorkspaceHeader';
import { WorkspaceTitle } from '../layout/WorkspaceTitle';
import { DataFilter } from '../dataTable/DataFilter';
import { KeyspaceLink } from '../links/KeyspaceLink';
import { TabletLink } from '../links/TabletLink';
import { ExternalTabletLink } from '../links/ExternalTabletLink';

export const Tablets = () => {
useDocumentTitle('Tablets');
Expand Down Expand Up @@ -68,12 +70,20 @@ export const Tablets = () => {
)}
</KeyspaceLink>
</DataCell>
<DataCell className="white-space-nowrap">
<TabletServingPip state={t._raw.state} /> {t.type}
<DataCell>
<TabletLink alias={t.alias} className="font-weight-bold" clusterID={t._raw.cluster?.id}>
{t.alias}
</TabletLink>
</DataCell>
<DataCell className="white-space-nowrap">{t.type}</DataCell>

<DataCell>
<TabletServingPip state={t._raw.state} /> {t.state}
</DataCell>

<DataCell>
<ExternalTabletLink fqdn={`//${t._raw.FQDN}`}>{t.hostname}</ExternalTabletLink>
</DataCell>
<DataCell>{t.state}</DataCell>
<DataCell>{t.alias}</DataCell>
<DataCell>{t.hostname}</DataCell>
</tr>
));
},
Expand All @@ -94,7 +104,7 @@ export const Tablets = () => {
value={filter || ''}
/>
<DataTable
columns={['Keyspace', 'Shard', 'Type', 'Tablet State', 'Alias', 'Hostname']}
columns={['Keyspace', 'Shard', 'Alias', 'Type', 'Tablet State', 'Hostname']}
data={filteredData}
renderRows={renderRows}
/>
Expand Down
7 changes: 6 additions & 1 deletion web/vtadmin/src/components/routes/Workflow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { formatAlias } from '../../util/tablets';
import { useDocumentTitle } from '../../hooks/useDocumentTitle';
import { formatDateTime } from '../../util/time';
import { KeyspaceLink } from '../links/KeyspaceLink';
import { TabletLink } from '../links/TabletLink';

interface RouteParams {
clusterID: string;
Expand Down Expand Up @@ -100,7 +101,11 @@ export const Workflow = () => {
<span className="text-color-secondary">N/A</span>
)}
</DataCell>
<DataCell>{formatAlias(row.tablet)}</DataCell>
<DataCell>
<TabletLink alias={formatAlias(row.tablet)} clusterID={clusterID}>
{formatAlias(row.tablet)}
</TabletLink>
</DataCell>
</tr>
);
});
Expand Down
15 changes: 10 additions & 5 deletions web/vtadmin/src/components/routes/keyspace/KeyspaceShards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ import { DataFilter } from '../../dataTable/DataFilter';
import { useSyncedURLParam } from '../../../hooks/useSyncedURLParam';
import { filterNouns } from '../../../util/filterNouns';
import { ContentContainer } from '../../layout/ContentContainer';
import { TabletLink } from '../../links/TabletLink';
interface Props {
keyspace: pb.Keyspace | null | undefined;
}

type ShardState = 'SERVING' | 'NOT_SERVING';

const TABLE_COLUMNS = ['Shard', 'Tablet', 'Tablet State', 'Alias', 'Hostname'];
const TABLE_COLUMNS = ['Shard', 'Alias', 'Tablet Type', 'Tablet State', 'Hostname'];
const PAGE_SIZE = 16;

export const KeyspaceShards = ({ keyspace }: Props) => {
Expand Down Expand Up @@ -87,10 +88,14 @@ export const KeyspaceShards = ({ keyspace }: Props) => {
</DataCell>
)}
<DataCell>
<TabletServingPip state={tablet._tabletStateEnum} /> {tablet.tabletType}
<TabletLink alias={tablet.alias} clusterID={keyspace?.cluster?.id}>
{tablet.alias}
</TabletLink>
</DataCell>
<DataCell>{tablet.tabletType}</DataCell>
<DataCell>
<TabletServingPip state={tablet._tabletStateEnum} /> {tablet.tabletState}
</DataCell>
<DataCell>{tablet.tabletState}</DataCell>
<DataCell>{tablet.alias}</DataCell>
<DataCell>{tablet.hostname}</DataCell>
</tr>
);
Expand All @@ -99,7 +104,7 @@ export const KeyspaceShards = ({ keyspace }: Props) => {
return acc;
}, [] as JSX.Element[]);
},
[filter, keyspace?.keyspace?.name]
[filter, keyspace?.cluster?.id, keyspace?.keyspace?.name]
);

if (!keyspace) {
Expand Down
54 changes: 54 additions & 0 deletions web/vtadmin/src/components/routes/tablet/Tablet.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Copyright 2021 The Vitess Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.headingMeta {
display: flex;
}

.headingMeta span {
display: inline-block;
line-height: 2;

&::after {
color: var(--colorScaffoldingHighlight);
content: '/';
display: inline-block;
margin: 0 1.2rem;
}

&:last-child::after {
content: none;
}
}

.placeholder {
align-items: center;
display: flex;
flex-direction: column;
font-size: var(--fontSizeLarge);
justify-content: center;
margin: 25vh auto;
max-width: 720px;
text-align: center;

h1 {
margin: 1.6rem 0;
}
}

.errorEmoji {
display: block;
font-size: 5.6rem;
}
Loading

0 comments on commit 3d45c22

Please sign in to comment.