You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.tsx 3.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { ExperimentStatus } from '@/enums';
  2. import { getQueryByExperimentLog } from '@/services/experiment/index.js';
  3. import { to } from '@/utils/promise';
  4. import classNames from 'classnames';
  5. import dayjs from 'dayjs';
  6. import React, { useCallback, useEffect, useRef, useState } from 'react';
  7. import LogGroup from '../LogGroup';
  8. import styles from './index.less';
  9. export type ExperimentLog = {
  10. log_type: 'normal' | 'resource'; // 日志类型
  11. pod_name?: string; // 分布式名称
  12. log_content?: string; // 日志内容
  13. start_time?: string; // 日志开始时间
  14. };
  15. type LogListProps = {
  16. /** 实验实例 name */
  17. instanceName: string;
  18. /** 实验实例 namespace */
  19. instanceNamespace: string;
  20. /** 流水线节点 id */
  21. pipelineNodeId: string;
  22. /** 实验实例工作流 id */
  23. workflowId?: string;
  24. /** 实验实例节点开始运行时间 */
  25. instanceNodeStartTime?: string;
  26. /** 实验实例节点运行状态 */
  27. instanceNodeStatus?: ExperimentStatus;
  28. /** 自定义类名 */
  29. className?: string;
  30. /** 自定义样式 */
  31. style?: React.CSSProperties;
  32. };
  33. function LogList({
  34. instanceName,
  35. instanceNamespace,
  36. pipelineNodeId,
  37. workflowId,
  38. instanceNodeStartTime,
  39. instanceNodeStatus,
  40. className,
  41. style,
  42. }: LogListProps) {
  43. const [logGroups, setLogGroups] = useState<ExperimentLog[]>([]);
  44. const retryRef = useRef(3); // 等待 2 秒,重试 3 次
  45. // 获取实验 Pods 组
  46. const getExperimentLog = useCallback(async () => {
  47. const start_time = dayjs(instanceNodeStartTime).valueOf() * 1.0e6;
  48. const params = {
  49. task_id: pipelineNodeId,
  50. component_id: workflowId,
  51. name: instanceName,
  52. namespace: instanceNamespace,
  53. start_time: start_time,
  54. };
  55. const [res] = await to(getQueryByExperimentLog(params));
  56. if (res && res.data) {
  57. const { log_type, pods, log_detail } = res.data;
  58. if (log_type === 'normal') {
  59. const list = [
  60. {
  61. ...log_detail,
  62. log_type,
  63. },
  64. ];
  65. setLogGroups(list);
  66. } else if (log_type === 'resource') {
  67. const list = pods.map((v: string) => ({
  68. log_type,
  69. pod_name: v,
  70. log_content: '',
  71. start_time,
  72. }));
  73. setLogGroups(list);
  74. }
  75. } else {
  76. if (retryRef.current > 0) {
  77. retryRef.current -= 1;
  78. setTimeout(() => {
  79. getExperimentLog();
  80. }, 2 * 1000);
  81. }
  82. }
  83. }, [pipelineNodeId, workflowId, instanceName, instanceNamespace, instanceNodeStartTime]);
  84. // 当实例节点运行状态不是 Pending,获取实验日志组
  85. useEffect(() => {
  86. if (
  87. instanceNodeStatus &&
  88. instanceNodeStatus !== ExperimentStatus.Pending &&
  89. logGroups.length === 0
  90. ) {
  91. getExperimentLog();
  92. }
  93. }, [getExperimentLog, logGroups, instanceNodeStatus]);
  94. return (
  95. <div className={classNames(styles['log-list'], className)} id="log-list" style={style}>
  96. {logGroups.length > 0 ? (
  97. logGroups.map((v) => <LogGroup key={v.pod_name} {...v} status={instanceNodeStatus} />)
  98. ) : (
  99. <div className={styles['log-list__empty']}>暂无日志</div>
  100. )}
  101. </div>
  102. );
  103. }
  104. export default LogList;