1import { Log } from '@kubernetes/client-node' 9const podColors = [chalkCyan, chalkGreen, chalkMagenta, chalkYellow] 18 streamStdout?: boolean 21export const ret1PodLogs = async (props: Ret1PodLogsProps) => { 22 const {podName, containerName, cluster_name, tailLines, follow = false, pretty = false, timestamps = false, streamStdout = false} = props 26 throPtErr('cluster offline', {cluster_name, offlineReason, what: 'retPodLogs'}) 31 const log = new Log(kubeConfig) 32 const stream = new nodeStream.PassThrough() 34 stream.pipe(process.stdout) 38 stream.on('data', (chunk) => { 42 // Set up end listener BEFORE calling log.log() to avoid race condition 43 const endPromise = new Promise<string>((resolve) => { 44 stream.on('end', () => resolve(retStr)) 47 const namespace = 'default' 50 await log.log(namespace, podName, containerName, stream, {follow, tailLines, pretty, timestamps}) 51 return await endPromise 55 return await new Promise<string>((resolve, reject) => { 56 const timer = setTimeout(() => { 58 reject(new Error(`k8s log timeout (${timeoutMs}ms) cluster=${cluster_name}`)) 61 endPromise.then((str) => { clearTimeout(timer); resolve(str) }) 63 log.log(namespace, podName, containerName, stream, {follow, tailLines, pretty, timestamps}) 64 .catch((err) => { clearTimeout(timer); reject(err) }) 68type PodInfo = {podName: string, containerName: string} 75export const retMultiPodLogs = async (props: RetMultiPodLogsProps) => { 76 const {pods, cluster_name, tailLines, follow = false} = props 78 const log = new Log(kubeConfig) 79 const namespace = 'default' 81 const streamPromises = pods.map(async ({podName, containerName}, idx) => { 82 const colorFn = podColors[idx % podColors.length] 83 const podShort = podName.slice(-8) 84 const prefix = colorFn(`[${podShort}]`) 86 const stream = new nodeStream.PassThrough() 88 stream.on('data', (chunk: Buffer) => { 89 buffer += chunk.toString() 90 const lines = buffer.split('\n') 91 buffer = lines.pop() || '' 92 for (const line of lines) { 93 process.stdout.write(`${prefix} ${line}\n`) 96 stream.on('end', () => { 97 if (buffer) process.stdout.write(`${prefix} ${buffer}\n`) 100 // Set up end listener BEFORE calling log.log() to avoid race condition 101 const endPromise = new Promise<void>((resolve) => stream.on('end', resolve)) 102 await log.log(namespace, podName, containerName, stream, {follow, tailLines, pretty: true, timestamps: false}) 106 await Promise.all(streamPromises)