This commit is contained in:
2025-11-27 17:26:53 +03:00
parent 5222cceb81
commit eef82577ab
11 changed files with 333 additions and 160 deletions

View File

@@ -38,29 +38,6 @@ const io = new Server(server, {
jobService.setSocket(io);
let counter = 0;
let counterTimer: NodeJS.Timeout | null = null;
const broadcastCounter = () => {
io.emit("counter:update", { value: counter });
};
const startCounter = () => {
if (counterTimer) return;
counterTimer = setInterval(() => {
counter += 1;
broadcastCounter();
}, 1000);
};
const stopCounter = () => {
if (counterTimer) {
clearInterval(counterTimer);
counterTimer = null;
}
io.emit("counter:stopped", { value: counter });
};
io.use((socket, next) => {
const token = socket.handshake.auth?.token as string | undefined;
if (!token) {
@@ -81,20 +58,6 @@ io.on("connection", (socket) => {
socket.emit("pong", "pong");
});
socket.on("counter:start", (ack?: (payload: { running: boolean; value: number }) => void) => {
startCounter();
ack?.({ running: true, value: counter });
});
socket.on("counter:stop", (ack?: (payload: { running: boolean; value: number }) => void) => {
stopCounter();
ack?.({ running: false, value: counter });
});
socket.on("counter:status", (ack?: (payload: { running: boolean; value: number }) => void) => {
ack?.({ running: !!counterTimer, value: counter });
});
socket.on("job:subscribe", async ({ jobId }: { jobId: string }) => {
if (!jobId) return;
socket.join(`job:${jobId}`);

View File

@@ -25,6 +25,52 @@ router.get("/", async (_req, res) => {
);
});
router.get("/metrics/summary", async (_req, res) => {
const since = new Date();
since.setDate(since.getDate() - 7);
const dailyStats = await JobRun.aggregate([
{ $match: { startedAt: { $gte: since } } },
{
$group: {
_id: { $dateToString: { format: "%Y-%m-%d", date: "$startedAt" } },
total: { $sum: 1 },
success: {
$sum: {
$cond: [{ $eq: ["$status", "success"] }, 1, 0]
}
},
failed: {
$sum: {
$cond: [{ $eq: ["$status", "failed"] }, 1, 0]
}
},
avgDurationMs: { $avg: "$durationMs" }
}
},
{ $sort: { _id: 1 } }
]);
const recentRuns = await JobRun.find()
.sort({ startedAt: -1 })
.limit(10)
.populate("job", "name repoUrl status")
.lean();
const successTotal = dailyStats.reduce((acc, d) => acc + (d.success || 0), 0);
const totalRuns = dailyStats.reduce((acc, d) => acc + (d.total || 0), 0);
const successRate = totalRuns ? Math.round((successTotal / totalRuns) * 100) : 0;
return res.json({
dailyStats,
recentRuns,
totals: {
successRate,
totalRuns
}
});
});
router.get("/:id", async (req, res) => {
const { id } = req.params;
const job = await Job.findById(id).lean();

View File

@@ -34,8 +34,15 @@ function runCommand(command: string, cwd: string, onData: (chunk: string) => voi
env: { ...process.env, CI: process.env.CI || "1" }
});
child.stdout.on("data", (data) => onData(cleanOutput(data.toString())));
child.stderr.on("data", (data) => onData(cleanOutput(data.toString())));
const emitLines = (chunk: Buffer) => {
const cleaned = cleanOutput(chunk.toString()).replace(/\r\n|\r/g, "\n");
cleaned.split("\n").forEach((line) => {
onData(line);
});
};
child.stdout.on("data", emitLines);
child.stderr.on("data", emitLines);
child.on("error", (err) => {
onData(`Hata: ${err.message}`);