|
|
@@ -4,9 +4,7 @@ import React, {
|
|
|
useRef,
|
|
|
useState,
|
|
|
} from "react";
|
|
|
-
|
|
|
import styled from "styled-components";
|
|
|
-
|
|
|
import spinner from "assets/loading.gif";
|
|
|
import api from "shared/api";
|
|
|
import { useLogs } from "./utils";
|
|
|
@@ -27,6 +25,9 @@ import { useRevisionList } from "lib/hooks/useRevisionList";
|
|
|
import { useLocation } from "react-router";
|
|
|
import { useLatestRevision } from "../../app-view/LatestRevisionContext";
|
|
|
import Filter from "components/porter/Filter";
|
|
|
+import { useTimer } from 'react-timer-hook';
|
|
|
+import { useIntercom } from "lib/hooks/useIntercom";
|
|
|
+import axios from "axios";
|
|
|
|
|
|
type Props = {
|
|
|
projectId: number;
|
|
|
@@ -44,6 +45,8 @@ type Props = {
|
|
|
appId: number;
|
|
|
};
|
|
|
|
|
|
+const DEFAULT_LOG_TIMEOUT_SECONDS = 60;
|
|
|
+
|
|
|
const Logs: React.FC<Props> = ({
|
|
|
projectId,
|
|
|
clusterId,
|
|
|
@@ -65,7 +68,7 @@ const Logs: React.FC<Props> = ({
|
|
|
revision_id: queryParams.get('revision_id'),
|
|
|
}
|
|
|
|
|
|
- const scrollToBottomRef = useRef<HTMLDivElement | undefined>(undefined);
|
|
|
+ const scrollToBottomRef = useRef<HTMLDivElement | null>(null);
|
|
|
const [scrollToBottomEnabled, setScrollToBottomEnabled] = useState(true);
|
|
|
const [enteredSearchText, setEnteredSearchText] = useState("");
|
|
|
const [searchText, setSearchText] = useState("");
|
|
|
@@ -88,6 +91,8 @@ const Logs: React.FC<Props> = ({
|
|
|
const { revisionIdToNumber } = useRevisionList({ appName, deploymentTargetId, projectId, clusterId });
|
|
|
const { latestRevision: { revision_number: latestRevisionNumber } } = useLatestRevision();
|
|
|
|
|
|
+ const { showIntercomWithMessage } = useIntercom();
|
|
|
+
|
|
|
const isAgentVersionUpdated = (agentImage: string | undefined) => {
|
|
|
if (agentImage == null) {
|
|
|
return false;
|
|
|
@@ -182,7 +187,7 @@ const Logs: React.FC<Props> = ({
|
|
|
}, 5000);
|
|
|
};
|
|
|
|
|
|
- const { logs, refresh, moveCursor, paginationInfo } = useLogs({
|
|
|
+ const { logs, refresh, moveCursor, paginationInfo, stopLogStream } = useLogs({
|
|
|
projectID: projectId,
|
|
|
clusterID: clusterId,
|
|
|
selectedFilterValues,
|
|
|
@@ -199,6 +204,20 @@ const Logs: React.FC<Props> = ({
|
|
|
appID: appId,
|
|
|
});
|
|
|
|
|
|
+ const { totalSeconds, isRunning, pause: pauseLogTimeout, restart: restartLogTimeout } = useTimer({
|
|
|
+ expiryTimestamp: dayjs().add(DEFAULT_LOG_TIMEOUT_SECONDS, 'seconds').toDate(),
|
|
|
+ onExpire: () => {
|
|
|
+ stopLogStream();
|
|
|
+ showIntercomWithMessage({ message: "I am having trouble receiving logs from my application." });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (logs.length) {
|
|
|
+ pauseLogTimeout();
|
|
|
+ }
|
|
|
+ },[logs.length]);
|
|
|
+
|
|
|
useEffect(() => {
|
|
|
setFilters([
|
|
|
{
|
|
|
@@ -309,6 +328,7 @@ const Logs: React.FC<Props> = ({
|
|
|
<Spacer inline x={1} />
|
|
|
<ScrollButton
|
|
|
onClick={() => {
|
|
|
+ restartLogTimeout(dayjs().add(DEFAULT_LOG_TIMEOUT_SECONDS, 'seconds').toDate());
|
|
|
refresh({ isLive: selectedDate == null && timeRange?.endTime == null });
|
|
|
}}
|
|
|
>
|
|
|
@@ -320,7 +340,7 @@ const Logs: React.FC<Props> = ({
|
|
|
<Spacer y={0.5} />
|
|
|
<LogsSectionWrapper>
|
|
|
<StyledLogsSection>
|
|
|
- {isLoading && <Loading message="Waiting for logs..." />}
|
|
|
+ {isLoading && <Loading message={"Initializing..."} />}
|
|
|
{!isLoading && logs.length !== 0 && (
|
|
|
<>
|
|
|
<LoadMoreButton
|
|
|
@@ -355,8 +375,20 @@ const Logs: React.FC<Props> = ({
|
|
|
</Highlight>
|
|
|
</Message>
|
|
|
)}
|
|
|
- {!isLoading && logs.length === 0 && selectedDate == null && (
|
|
|
- <Loading message="Waiting for logs..." />
|
|
|
+ {!isLoading && logs.length === 0 && selectedDate == null && isRunning && (
|
|
|
+ <Loading message={`Waiting ${totalSeconds} seconds for logs...`} />
|
|
|
+ )}
|
|
|
+ {!isLoading && logs.length === 0 && selectedDate == null && !isRunning && (
|
|
|
+ <Message>
|
|
|
+ Timed out waiting for logs.
|
|
|
+ <Highlight onClick={() => {
|
|
|
+ restartLogTimeout(dayjs().add(DEFAULT_LOG_TIMEOUT_SECONDS, 'seconds').toDate());
|
|
|
+ refresh({ isLive: selectedDate == null && timeRange?.endTime == null });
|
|
|
+ }}>
|
|
|
+ <i className="material-icons">autorenew</i>
|
|
|
+ Refresh
|
|
|
+ </Highlight>
|
|
|
+ </Message>
|
|
|
)}
|
|
|
<div ref={scrollToBottomRef} />
|
|
|
</StyledLogsSection>
|
|
|
@@ -400,7 +432,7 @@ const Logs: React.FC<Props> = ({
|
|
|
notify("Porter agent is outdated. Please upgrade to see logs.");
|
|
|
}
|
|
|
} catch (err) {
|
|
|
- if (err.response?.status === 404) {
|
|
|
+ if (axios.isAxiosError(err) && err.response?.status === 404) {
|
|
|
setHasPorterAgent(false);
|
|
|
}
|
|
|
}
|
|
|
@@ -534,8 +566,8 @@ const Message = styled.div`
|
|
|
justify-content: center;
|
|
|
margin-left: 75px;
|
|
|
text-align: center;
|
|
|
- color: #ffffff44;
|
|
|
font-size: 13px;
|
|
|
+ color: #aaaabb;
|
|
|
`;
|
|
|
|
|
|
const Highlight = styled.div`
|