Skip to content

Commit

Permalink
fix: log stream cannot be used with jsonRes after flushHeader (#5064)
Browse files Browse the repository at this point in the history
  • Loading branch information
zijiren233 authored Sep 11, 2024
1 parent 22e4ff2 commit 97939b5
Showing 1 changed file with 76 additions and 72 deletions.
148 changes: 76 additions & 72 deletions frontend/providers/applaunchpad/src/pages/api/getPodLogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,59 @@ import { jsonRes } from '@/services/backend/response';
import { Log } from '@kubernetes/client-node';
import { PassThrough } from 'stream';

// get App Metrics By DeployName. compute average value
export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResp>) {
const { kc, k8sCore, namespace } = await getK8s({
kubeconfig: await authSession(req.headers)
});

const {
appName,
podName,
stream = false,
logSize,
previous,
sinceTime
} = req.body as {
appName: string;
podName: string;
stream: boolean;
logSize?: number;
previous?: boolean;
sinceTime?: number;
};

if (!podName) {
throw new Error('podName is empty');
}

if (!stream) {
const sinceSeconds =
sinceTime && !!!previous ? Math.floor((Date.now() - sinceTime) / 1000) : undefined;
try {
const { body: data } = await k8sCore.readNamespacedPodLog(
podName,
namespace,
appName,
undefined,
undefined,
undefined,
undefined,
previous,
sinceSeconds,
logSize
);
return jsonRes(res, {
data
});
} catch (error) {
console.log('error: ', error);
return jsonRes(res, {
code: 500,
error
});
}
}

let streamResponse: any;
const logStream = new PassThrough();

Expand All @@ -29,92 +80,45 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
destroyStream();
});

try {
const {
appName,
podName,
stream = false,
logSize,
previous,
sinceTime
} = req.body as {
appName: string;
podName: string;
stream: boolean;
logSize?: number;
previous?: boolean;
sinceTime?: number;
};

if (!podName) {
throw new Error('podName is empty');
}
// Set headers for streaming response
res.setHeader('Content-Type', 'text/event-stream;charset=utf-8');
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('X-Accel-Buffering', 'no');
res.setHeader('Cache-Control', 'no-cache, no-transform');

const { kc, k8sCore, namespace } = await getK8s({
kubeconfig: await authSession(req.headers)
});
res.flushHeaders();

if (!stream) {
const sinceSeconds =
sinceTime && !!!previous ? Math.floor((Date.now() - sinceTime) / 1000) : undefined;
// get pods
const { body: data } = await k8sCore.readNamespacedPodLog(
podName,
namespace,
appName,
undefined,
undefined,
undefined,
undefined,
previous,
sinceSeconds,
logSize
);
return jsonRes(res, {
data
});
}

const logs = new Log(kc);
logStream.pipe(res);

res.setHeader('Content-Type', 'text/event-stream;charset-utf-8');
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('X-Accel-Buffering', 'no');
res.setHeader('Cache-Control', 'no-cache, no-transform');
logStream.pipe(res);
const reqData = {
follow: true,
pretty: false,
timestamps: false,
tailLines: 1000,
previous: !!previous
} as any;

const reqData = {
follow: true,
pretty: false,
timestamps: false,
tailLines: 1000,
previous: !!previous
} as any;
if (!reqData.previous && sinceTime) {
reqData.sinceTime = timestampToRFC3339(sinceTime);
}

if (!reqData.previous) {
res.flushHeaders();
}
if (!reqData.previous && sinceTime) {
reqData.sinceTime = timestampToRFC3339(sinceTime);
}

const logs = new Log(kc);
try {
streamResponse = await logs.log(
namespace,
podName,
appName,
logStream,
(err) => {
console.log('err', err);
if (err) {
console.log('err', err);
res.write(err.toString());
}
destroyStream();
},
reqData
);
} catch (err: any) {
jsonRes(res, {
code: 500,
error: err
});
}
} catch (err: any) {}
}

function timestampToRFC3339(timestamp: number) {
Expand Down

0 comments on commit 97939b5

Please sign in to comment.