提交 399048a6 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 78f4550b
......@@ -12,6 +12,7 @@
"axios": "^1.13.0",
"cors": "^2.8.5",
"cross-env": "^7.0.3",
"dayjs": "^1.11.19",
"dotenv": "^16.4.5",
"express": "^4.21.1",
"mongoose": "^8.8.0",
......@@ -669,6 +670,12 @@
"node": "*"
}
},
"node_modules/dayjs": {
"version": "1.11.19",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz",
"integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==",
"license": "MIT"
},
"node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
......
......@@ -26,6 +26,7 @@
"axios": "^1.13.0",
"cors": "^2.8.5",
"cross-env": "^7.0.3",
"dayjs": "^1.11.19",
"dotenv": "^16.4.5",
"express": "^4.21.1",
"mongoose": "^8.8.0",
......
import mongoose from 'mongoose'
import dayjs from 'dayjs'
// 最大存储大小(字符数)
const MAX_BODY_SIZE = 2000
......@@ -92,9 +93,16 @@ const logSchema = new mongoose.Schema(
userAgent: String,
ip: String,
url: String,
createdAt: String,
updatedAt: String,
},
{
timestamps: true,
timestamps: {
// 返回服务器本地时间格式的字符串:YYYY-MM-DD HH:mm:ss
currentTime: () => {
return dayjs().format('YYYY-MM-DD HH:mm:ss')
},
},
versionKey: false,
}
)
......@@ -123,8 +131,9 @@ logSchema.pre('insertMany', function (next, docs) {
next()
})
// TTL index: auto delete logs after 360 days
logSchema.index({ createdAt: 1 }, { expireAfterSeconds: 360 * 24 * 60 * 60 })
// 注意:TTL 索引需要 Date 类型,但 createdAt 现在是字符串类型
// 如果需要自动删除功能,需要添加一个 Date 类型的字段用于 TTL,或者使用定时任务删除
// logSchema.index({ createdAt: 1 }, { expireAfterSeconds: 360 * 24 * 60 * 60 })
// Compound index for common queries
logSchema.index({ type: 1, appName: 1, createdAt: -1 })
......
import Log from './logs.model.js'
import dayjs from 'dayjs'
export const create = async (logData) => {
const log = new Log(logData)
......@@ -21,8 +22,9 @@ export const query = async (filters = {}, options = {}) => {
if (filters.userId) query.userId = filters.userId
if (filters.startTime || filters.endTime) {
query.createdAt = {}
if (filters.startTime) query.createdAt.$gte = new Date(filters.startTime)
if (filters.endTime) query.createdAt.$lte = new Date(filters.endTime)
// createdAt 是字符串格式 YYYY-MM-DD HH:mm:ss,直接使用字符串比较
if (filters.startTime) query.createdAt.$gte = filters.startTime
if (filters.endTime) query.createdAt.$lte = filters.endTime
}
if (filters.keyword) {
query.message = { $regex: filters.keyword, $options: 'i' }
......@@ -44,18 +46,15 @@ export const query = async (filters = {}, options = {}) => {
}
}
// 获取今日开始时间
// 获取今日开始时间(服务器本地时间,字符串格式 YYYY-MM-DD HH:mm:ss)
const getTodayStart = () => {
const today = new Date()
today.setHours(0, 0, 0, 0)
return today
return dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss')
}
// 获取昨日时间范围
// 获取昨日时间范围(服务器本地时间,字符串格式)
const getYesterdayRange = () => {
const today = getTodayStart()
const yesterday = new Date(today)
yesterday.setDate(yesterday.getDate() - 1)
const today = dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss')
const yesterday = dayjs().subtract(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss')
return { start: yesterday, end: today }
}
......@@ -67,7 +66,7 @@ export const getStats = async (filters = {}) => {
if (filters.appName) baseMatch.appName = filters.appName
// 并行查询所有统计数据
const [todayTotal, yesterdayTotal, todayErrors, yesterdayErrors, todayApps, yesterdayApps, hourlyTrend, recentLogs] =
const [todayTotal, yesterdayTotal, todayErrors, yesterdayErrors, todayApps, yesterdayApps, recentLogs] =
await Promise.all([
// 今日日志总数
Log.countDocuments({ ...baseMatch, createdAt: { $gte: todayStart } }),
......@@ -85,17 +84,6 @@ export const getStats = async (filters = {}) => {
Log.distinct('appName', { ...baseMatch, createdAt: { $gte: todayStart } }),
// 昨日活跃应用数
Log.distinct('appName', { ...baseMatch, createdAt: { $gte: yesterdayStart, $lt: yesterdayEnd } }),
// 按小时分组的趋势(今日)
Log.aggregate([
{ $match: { ...baseMatch, createdAt: { $gte: todayStart } } },
{
$group: {
_id: { $hour: '$createdAt' },
count: { $sum: 1 },
},
},
{ $sort: { _id: 1 } },
]),
// 最近日志
Log.find(baseMatch).sort({ createdAt: -1 }).limit(10).lean(),
])
......@@ -106,12 +94,6 @@ export const getStats = async (filters = {}) => {
return Number((((today - yesterday) / yesterday) * 100).toFixed(1))
}
// 填充24小时趋势数据
const trend = Array.from({ length: 24 }, (_, hour) => {
const found = hourlyTrend.find((h) => h._id === hour)
return { hour, count: found?.count || 0 }
})
return {
// 今日日志
todayTotal: {
......@@ -128,8 +110,6 @@ export const getStats = async (filters = {}) => {
count: todayApps.length,
change: todayApps.length - yesterdayApps.length,
},
// 按小时趋势
trend,
// 最近日志
recentLogs,
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论