fixes
parent
4c47e3e9f0
commit
ca0b70a52a
|
|
@ -3672,77 +3672,72 @@ class KubernetesTaskRunner {
|
||||||
let didStreamAnyLogs = false;
|
let didStreamAnyLogs = false;
|
||||||
let shouldReadLogs = true;
|
let shouldReadLogs = true;
|
||||||
let shouldCleanup = true;
|
let shouldCleanup = true;
|
||||||
try {
|
// eslint-disable-next-line no-constant-condition
|
||||||
// eslint-disable-next-line no-constant-condition
|
while (true) {
|
||||||
while (true) {
|
let sinceTime = ``;
|
||||||
let sinceTime = ``;
|
if (`${KubernetesTaskRunner.lastReceivedTimestamp}` !== ``) {
|
||||||
if (`${KubernetesTaskRunner.lastReceivedTimestamp}` !== ``) {
|
const currentDate = new Date(KubernetesTaskRunner.lastReceivedTimestamp);
|
||||||
const currentDate = new Date(KubernetesTaskRunner.lastReceivedTimestamp);
|
const dateTimeIsoString = currentDate.toISOString();
|
||||||
const dateTimeIsoString = currentDate.toISOString();
|
// k8s compatible iso date format - split by dot - https://www.googlecloudcommunity.com/gc/Apigee/JS-for-current-timestamp-in-W3C-WSDL-date-format-YYYY-MM-DDThh/td-p/68415
|
||||||
// k8s compatible iso date format - split by dot - https://www.googlecloudcommunity.com/gc/Apigee/JS-for-current-timestamp-in-W3C-WSDL-date-format-YYYY-MM-DDThh/td-p/68415
|
const currentDateTime = dateTimeIsoString.split('.')[0];
|
||||||
const currentDateTime = dateTimeIsoString.split('.')[0];
|
const timeZoneOffset = currentDate.getTimezoneOffset();
|
||||||
const timeZoneOffset = currentDate.getTimezoneOffset();
|
const positiveOffset = Math.abs(timeZoneOffset);
|
||||||
const positiveOffset = Math.abs(timeZoneOffset);
|
const timeOffsetInHours = -(timeZoneOffset / 60);
|
||||||
const timeOffsetInHours = -(timeZoneOffset / 60);
|
const minZone = positiveOffset - Math.floor(timeOffsetInHours) * 60;
|
||||||
const minZone = positiveOffset - Math.floor(timeOffsetInHours) * 60;
|
const symbolOffset = timeZoneOffset > 0 ? '-' : '+';
|
||||||
const symbolOffset = timeZoneOffset > 0 ? '-' : '+';
|
const hourOffset = Math.floor(timeOffsetInHours) < 10 ? 0 : '';
|
||||||
const hourOffset = Math.floor(timeOffsetInHours) < 10 ? 0 : '';
|
const minOffset = minZone < 10 ? 0 : '';
|
||||||
const minOffset = minZone < 10 ? 0 : '';
|
const tzd = `${symbolOffset + hourOffset + Math.floor(timeOffsetInHours)}:${minOffset}${minZone}`;
|
||||||
const tzd = `${symbolOffset + hourOffset + Math.floor(timeOffsetInHours)}:${minOffset}${minZone}`;
|
const dateTZDformat = currentDateTime + tzd;
|
||||||
const dateTZDformat = currentDateTime + tzd;
|
sinceTime = ` --since-time="${dateTZDformat}"`;
|
||||||
sinceTime = ` --since-time="${dateTZDformat}"`;
|
}
|
||||||
}
|
let lastMessageSeenIncludedInChunk = false;
|
||||||
let lastMessageSeenIncludedInChunk = false;
|
let lastMessageSeen = false;
|
||||||
let lastMessageSeen = false;
|
// using this instead of Kube
|
||||||
// using this instead of Kube
|
const logs = await cloud_runner_system_1.CloudRunnerSystem.Run(`kubectl logs ${podName} -f -c ${containerName} --timestamps${sinceTime}`, false, true);
|
||||||
const logs = await cloud_runner_system_1.CloudRunnerSystem.Run(`kubectl logs ${podName} -f -c ${containerName} --timestamps${sinceTime}`, false, true);
|
const splitLogs = logs.split(`\n`);
|
||||||
const splitLogs = logs.split(`\n`);
|
for (const chunk of splitLogs) {
|
||||||
for (const chunk of splitLogs) {
|
if (chunk.replace(/\s/g, ``) === KubernetesTaskRunner.lastReceivedMessage.replace(/\s/g, ``) &&
|
||||||
if (chunk.replace(/\s/g, ``) === KubernetesTaskRunner.lastReceivedMessage.replace(/\s/g, ``) &&
|
KubernetesTaskRunner.lastReceivedMessage.replace(/\s/g, ``) !== ``) {
|
||||||
KubernetesTaskRunner.lastReceivedMessage.replace(/\s/g, ``) !== ``) {
|
cloud_runner_logger_1.default.log(`Previous log message found ${chunk}`);
|
||||||
cloud_runner_logger_1.default.log(`Previous log message found ${chunk}`);
|
lastMessageSeenIncludedInChunk = true;
|
||||||
lastMessageSeenIncludedInChunk = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const chunk of splitLogs) {
|
|
||||||
const newDate = Date.parse(`${chunk.toString().split(`Z `)[0]}Z`);
|
|
||||||
if (chunk.replace(/\s/g, ``) === KubernetesTaskRunner.lastReceivedMessage.replace(/\s/g, ``)) {
|
|
||||||
lastMessageSeen = true;
|
|
||||||
}
|
|
||||||
if (lastMessageSeenIncludedInChunk && !lastMessageSeen) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
didStreamAnyLogs = true;
|
|
||||||
const message = cloud_runner_1.default.buildParameters.cloudRunnerDebug ? chunk : chunk.split(`Z `)[1];
|
|
||||||
KubernetesTaskRunner.lastReceivedMessage = chunk;
|
|
||||||
KubernetesTaskRunner.lastReceivedTimestamp = newDate;
|
|
||||||
({ shouldReadLogs, shouldCleanup, output } = follow_log_stream_service_1.FollowLogStreamService.handleIteration(message, shouldReadLogs, shouldCleanup, output));
|
|
||||||
}
|
|
||||||
if (!didStreamAnyLogs) {
|
|
||||||
core.error('Failed to stream any logs, listing namespace events, check for an error with the container');
|
|
||||||
core.error(JSON.stringify({
|
|
||||||
events: (await kubeClient.listNamespacedEvent(namespace)).body.items
|
|
||||||
.filter((x) => {
|
|
||||||
return x.involvedObject.name === podName || x.involvedObject.name === jobName;
|
|
||||||
})
|
|
||||||
.map((x) => {
|
|
||||||
return {
|
|
||||||
type: x.involvedObject.kind,
|
|
||||||
name: x.involvedObject.name,
|
|
||||||
message: x.message,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
}, undefined, 4));
|
|
||||||
throw new Error(`No logs streamed from k8s`);
|
|
||||||
}
|
|
||||||
if (follow_log_stream_service_1.FollowLogStreamService.DidReceiveEndOfTransmission) {
|
|
||||||
cloud_runner_logger_1.default.log('end of log stream');
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
for (const chunk of splitLogs) {
|
||||||
catch (error) {
|
const newDate = Date.parse(`${chunk.toString().split(`Z `)[0]}Z`);
|
||||||
cloud_runner_logger_1.default.log(`k8s stream watching failed ${JSON.stringify(error, undefined, 4)}`);
|
if (chunk.replace(/\s/g, ``) === KubernetesTaskRunner.lastReceivedMessage.replace(/\s/g, ``)) {
|
||||||
|
lastMessageSeen = true;
|
||||||
|
}
|
||||||
|
if (lastMessageSeenIncludedInChunk && !lastMessageSeen) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
didStreamAnyLogs = true;
|
||||||
|
const message = cloud_runner_1.default.buildParameters.cloudRunnerDebug ? chunk : chunk.split(`Z `)[1];
|
||||||
|
KubernetesTaskRunner.lastReceivedMessage = chunk;
|
||||||
|
KubernetesTaskRunner.lastReceivedTimestamp = newDate;
|
||||||
|
({ shouldReadLogs, shouldCleanup, output } = follow_log_stream_service_1.FollowLogStreamService.handleIteration(message, shouldReadLogs, shouldCleanup, output));
|
||||||
|
}
|
||||||
|
if (!didStreamAnyLogs) {
|
||||||
|
core.error('Failed to stream any logs, listing namespace events, check for an error with the container');
|
||||||
|
core.error(JSON.stringify({
|
||||||
|
events: (await kubeClient.listNamespacedEvent(namespace)).body.items
|
||||||
|
.filter((x) => {
|
||||||
|
return x.involvedObject.name === podName || x.involvedObject.name === jobName;
|
||||||
|
})
|
||||||
|
.map((x) => {
|
||||||
|
return {
|
||||||
|
type: x.involvedObject.kind,
|
||||||
|
name: x.involvedObject.name,
|
||||||
|
message: x.message,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
}, undefined, 4));
|
||||||
|
throw new Error(`No logs streamed from k8s`);
|
||||||
|
}
|
||||||
|
if (follow_log_stream_service_1.FollowLogStreamService.DidReceiveEndOfTransmission) {
|
||||||
|
cloud_runner_logger_1.default.log('end of log stream');
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -29,96 +29,92 @@ class KubernetesTaskRunner {
|
||||||
let shouldReadLogs = true;
|
let shouldReadLogs = true;
|
||||||
let shouldCleanup = true;
|
let shouldCleanup = true;
|
||||||
|
|
||||||
try {
|
// eslint-disable-next-line no-constant-condition
|
||||||
// eslint-disable-next-line no-constant-condition
|
while (true) {
|
||||||
while (true) {
|
let sinceTime = ``;
|
||||||
let sinceTime = ``;
|
if (`${KubernetesTaskRunner.lastReceivedTimestamp}` !== ``) {
|
||||||
if (`${KubernetesTaskRunner.lastReceivedTimestamp}` !== ``) {
|
const currentDate = new Date(KubernetesTaskRunner.lastReceivedTimestamp);
|
||||||
const currentDate = new Date(KubernetesTaskRunner.lastReceivedTimestamp);
|
const dateTimeIsoString = currentDate.toISOString();
|
||||||
const dateTimeIsoString = currentDate.toISOString();
|
|
||||||
|
|
||||||
// k8s compatible iso date format - split by dot - https://www.googlecloudcommunity.com/gc/Apigee/JS-for-current-timestamp-in-W3C-WSDL-date-format-YYYY-MM-DDThh/td-p/68415
|
// k8s compatible iso date format - split by dot - https://www.googlecloudcommunity.com/gc/Apigee/JS-for-current-timestamp-in-W3C-WSDL-date-format-YYYY-MM-DDThh/td-p/68415
|
||||||
const currentDateTime = dateTimeIsoString.split('.')[0];
|
const currentDateTime = dateTimeIsoString.split('.')[0];
|
||||||
const timeZoneOffset = currentDate.getTimezoneOffset();
|
const timeZoneOffset = currentDate.getTimezoneOffset();
|
||||||
const positiveOffset = Math.abs(timeZoneOffset);
|
const positiveOffset = Math.abs(timeZoneOffset);
|
||||||
const timeOffsetInHours = -(timeZoneOffset / 60);
|
const timeOffsetInHours = -(timeZoneOffset / 60);
|
||||||
const minZone = positiveOffset - Math.floor(timeOffsetInHours) * 60;
|
const minZone = positiveOffset - Math.floor(timeOffsetInHours) * 60;
|
||||||
const symbolOffset = timeZoneOffset > 0 ? '-' : '+';
|
const symbolOffset = timeZoneOffset > 0 ? '-' : '+';
|
||||||
const hourOffset = Math.floor(timeOffsetInHours) < 10 ? 0 : '';
|
const hourOffset = Math.floor(timeOffsetInHours) < 10 ? 0 : '';
|
||||||
const minOffset = minZone < 10 ? 0 : '';
|
const minOffset = minZone < 10 ? 0 : '';
|
||||||
const tzd = `${symbolOffset + hourOffset + Math.floor(timeOffsetInHours)}:${minOffset}${minZone}`;
|
const tzd = `${symbolOffset + hourOffset + Math.floor(timeOffsetInHours)}:${minOffset}${minZone}`;
|
||||||
const dateTZDformat = currentDateTime + tzd;
|
const dateTZDformat = currentDateTime + tzd;
|
||||||
sinceTime = ` --since-time="${dateTZDformat}"`;
|
sinceTime = ` --since-time="${dateTZDformat}"`;
|
||||||
}
|
}
|
||||||
let lastMessageSeenIncludedInChunk = false;
|
let lastMessageSeenIncludedInChunk = false;
|
||||||
let lastMessageSeen = false;
|
let lastMessageSeen = false;
|
||||||
|
|
||||||
// using this instead of Kube
|
// using this instead of Kube
|
||||||
const logs = await CloudRunnerSystem.Run(
|
const logs = await CloudRunnerSystem.Run(
|
||||||
`kubectl logs ${podName} -f -c ${containerName} --timestamps${sinceTime}`,
|
`kubectl logs ${podName} -f -c ${containerName} --timestamps${sinceTime}`,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
const splitLogs = logs.split(`\n`);
|
const splitLogs = logs.split(`\n`);
|
||||||
for (const chunk of splitLogs) {
|
for (const chunk of splitLogs) {
|
||||||
if (
|
if (
|
||||||
chunk.replace(/\s/g, ``) === KubernetesTaskRunner.lastReceivedMessage.replace(/\s/g, ``) &&
|
chunk.replace(/\s/g, ``) === KubernetesTaskRunner.lastReceivedMessage.replace(/\s/g, ``) &&
|
||||||
KubernetesTaskRunner.lastReceivedMessage.replace(/\s/g, ``) !== ``
|
KubernetesTaskRunner.lastReceivedMessage.replace(/\s/g, ``) !== ``
|
||||||
) {
|
) {
|
||||||
CloudRunnerLogger.log(`Previous log message found ${chunk}`);
|
CloudRunnerLogger.log(`Previous log message found ${chunk}`);
|
||||||
lastMessageSeenIncludedInChunk = true;
|
lastMessageSeenIncludedInChunk = true;
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const chunk of splitLogs) {
|
|
||||||
const newDate = Date.parse(`${chunk.toString().split(`Z `)[0]}Z`);
|
|
||||||
if (chunk.replace(/\s/g, ``) === KubernetesTaskRunner.lastReceivedMessage.replace(/\s/g, ``)) {
|
|
||||||
lastMessageSeen = true;
|
|
||||||
}
|
|
||||||
if (lastMessageSeenIncludedInChunk && !lastMessageSeen) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
didStreamAnyLogs = true;
|
|
||||||
const message = CloudRunner.buildParameters.cloudRunnerDebug ? chunk : chunk.split(`Z `)[1];
|
|
||||||
KubernetesTaskRunner.lastReceivedMessage = chunk;
|
|
||||||
KubernetesTaskRunner.lastReceivedTimestamp = newDate;
|
|
||||||
({ shouldReadLogs, shouldCleanup, output } = FollowLogStreamService.handleIteration(
|
|
||||||
message,
|
|
||||||
shouldReadLogs,
|
|
||||||
shouldCleanup,
|
|
||||||
output,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!didStreamAnyLogs) {
|
|
||||||
core.error('Failed to stream any logs, listing namespace events, check for an error with the container');
|
|
||||||
core.error(
|
|
||||||
JSON.stringify(
|
|
||||||
{
|
|
||||||
events: (await kubeClient.listNamespacedEvent(namespace)).body.items
|
|
||||||
.filter((x) => {
|
|
||||||
return x.involvedObject.name === podName || x.involvedObject.name === jobName;
|
|
||||||
})
|
|
||||||
.map((x) => {
|
|
||||||
return {
|
|
||||||
type: x.involvedObject.kind,
|
|
||||||
name: x.involvedObject.name,
|
|
||||||
message: x.message,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
undefined,
|
|
||||||
4,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
throw new Error(`No logs streamed from k8s`);
|
|
||||||
}
|
|
||||||
if (FollowLogStreamService.DidReceiveEndOfTransmission) {
|
|
||||||
CloudRunnerLogger.log('end of log stream');
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
for (const chunk of splitLogs) {
|
||||||
CloudRunnerLogger.log(`k8s stream watching failed ${JSON.stringify(error, undefined, 4)}`);
|
const newDate = Date.parse(`${chunk.toString().split(`Z `)[0]}Z`);
|
||||||
|
if (chunk.replace(/\s/g, ``) === KubernetesTaskRunner.lastReceivedMessage.replace(/\s/g, ``)) {
|
||||||
|
lastMessageSeen = true;
|
||||||
|
}
|
||||||
|
if (lastMessageSeenIncludedInChunk && !lastMessageSeen) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
didStreamAnyLogs = true;
|
||||||
|
const message = CloudRunner.buildParameters.cloudRunnerDebug ? chunk : chunk.split(`Z `)[1];
|
||||||
|
KubernetesTaskRunner.lastReceivedMessage = chunk;
|
||||||
|
KubernetesTaskRunner.lastReceivedTimestamp = newDate;
|
||||||
|
({ shouldReadLogs, shouldCleanup, output } = FollowLogStreamService.handleIteration(
|
||||||
|
message,
|
||||||
|
shouldReadLogs,
|
||||||
|
shouldCleanup,
|
||||||
|
output,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!didStreamAnyLogs) {
|
||||||
|
core.error('Failed to stream any logs, listing namespace events, check for an error with the container');
|
||||||
|
core.error(
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
events: (await kubeClient.listNamespacedEvent(namespace)).body.items
|
||||||
|
.filter((x) => {
|
||||||
|
return x.involvedObject.name === podName || x.involvedObject.name === jobName;
|
||||||
|
})
|
||||||
|
.map((x) => {
|
||||||
|
return {
|
||||||
|
type: x.involvedObject.kind,
|
||||||
|
name: x.involvedObject.name,
|
||||||
|
message: x.message,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
4,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
throw new Error(`No logs streamed from k8s`);
|
||||||
|
}
|
||||||
|
if (FollowLogStreamService.DidReceiveEndOfTransmission) {
|
||||||
|
CloudRunnerLogger.log('end of log stream');
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue