new file: log/access_blogbaster.log

new file:   src/pages/api/log.ts
	new file:   src/pages/log.tsx
	modified:   tsconfig.json
master
joker 2 years ago
parent 04ca57a2aa
commit 021680325e
  1. 5079
      log/access_blogbaster.log
  2. 45
      src/pages/api/log.ts
  3. 57
      src/pages/log.tsx
  4. 2
      tsconfig.json

File diff suppressed because it is too large Load Diff

@ -0,0 +1,45 @@
import fs from 'fs';
import type { NextApiRequest, NextApiResponse } from 'next';
// Путь к лог-файлу доступа Nginx
const logFilePath = '@../../log/access_blogbaster.log';
let log: string[] = [];
export default function handler(
req: NextApiRequest,
res: NextApiResponse
) {
// Чтение лог-файла
fs.readFile(logFilePath, 'utf8', (err, data) => {
if (err) throw err;
// Разбиваем содержимое файла на строки
const logLines = data.split('\n');
// Объект для хранения статистики
const mp3Stats: { [key: string]: number } = {};
// Анализируем каждую строку лога
logLines.forEach((line) => {
// Проверяем, содержит ли строка запрос к mp3 файлу
if (line.includes('.mp3')) {
const fileName = line.match(/\/([^/]+\.mp3)/)?.[1];
if (fileName) {
if (mp3Stats[fileName]) {
mp3Stats[fileName]++;
} else {
mp3Stats[fileName] = 1;
}
}
}
});
// Выводим статистику
for (const fileName in mp3Stats) {
log.push(fileName + ',' + mp3Stats[fileName]);
}
//let logData = JSON.stringify(log);
res.status(200).json(log);
});
}

@ -0,0 +1,57 @@
import React, { useState, useEffect } from 'react';
type LogData = {
fileName: string;
accessCount: number;
};
const LogTable: React.FC = () => {
const [logData, setLogData] = useState<LogData[]>([]);
useEffect(() => {
fetch('/api/log') // Обращаемся к REST API
.then((response) => response.json())
.then((data: string[]) => {
const parsedData: LogData[] = data.map((item: string) => {
const [fileName, accessCountStr] = item.split(",");
const accessCount: number = parseInt(accessCountStr);
return { fileName, accessCount };
});
setLogData(parsedData);
});
}, []);
return (
<div className="m-3 card lg:card-side bg-base-100 shadow-xl">
<div className="flex flex-col items-center bg-white border border-gray-200 rounded-lg shadow md:flex-row ">
<div className="mb-3 object-cover rounded-t-lg md:w-auto md:min-w-64 md:max-w-64 md:rounded-s-lg md:m-3">
<div>
<h2>Статистика доступа к mp3 файлам</h2>
<div className="container mx-auto p-6">
<table className="min-w-full bg-white border border-gray-300">
<thead>
<tr>
<th className="py-2 px-4 border-b"></th>
<th className="py-2 px-4 border-b">Имя файла</th>
<th className="py-2 px-4 border-b">Количество доступов</th>
</tr>
</thead>
<tbody>
{logData.map((item, index) => (
<tr key={index}>
<td className="py-2 px-4 border-b">{index + 1}</td>
<td className="py-2 px-4 border-b">{item.fileName}</td>
<td className="py-2 px-4 border-b">{item.accessCount}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
);
};
export default LogTable;

@ -22,6 +22,6 @@
"@/*": ["./src/*"] "@/*": ["./src/*"]
} }
}, },
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "src/pages/api/log.ts"],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }

Loading…
Cancel
Save