feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
class PerformanceMonitor {
|
||||
private metrics: Map<string, number[]> = new Map()
|
||||
private readonly MAX_SAMPLES = 100
|
||||
|
||||
startMeasure(operation: string): () => void {
|
||||
const startTime = performance.now()
|
||||
|
||||
return () => {
|
||||
const endTime = performance.now()
|
||||
const duration = endTime - startTime
|
||||
|
||||
this.recordMetric(operation, duration)
|
||||
|
||||
console.log(`[性能监控] ${operation}: ${duration.toFixed(2)}ms`)
|
||||
}
|
||||
}
|
||||
|
||||
recordMetric(operation: string, duration: number): void {
|
||||
if (!this.metrics.has(operation)) {
|
||||
this.metrics.set(operation, [])
|
||||
}
|
||||
|
||||
const samples = this.metrics.get(operation)!
|
||||
samples.push(duration)
|
||||
|
||||
if (samples.length > this.MAX_SAMPLES) {
|
||||
samples.shift()
|
||||
}
|
||||
}
|
||||
|
||||
getAverage(operation: string): number {
|
||||
const samples = this.metrics.get(operation)
|
||||
if (!samples || samples.length === 0) {
|
||||
return 0
|
||||
}
|
||||
|
||||
const sum = samples.reduce((acc, val) => acc + val, 0)
|
||||
return sum / samples.length
|
||||
}
|
||||
|
||||
getP95(operation: string): number {
|
||||
const samples = this.metrics.get(operation)
|
||||
if (!samples || samples.length === 0) {
|
||||
return 0
|
||||
}
|
||||
|
||||
const sorted = [...samples].sort((a, b) => a - b)
|
||||
const index = Math.floor(sorted.length * 0.95)
|
||||
return sorted[index]
|
||||
}
|
||||
|
||||
getP99(operation: string): number {
|
||||
const samples = this.metrics.get(operation)
|
||||
if (!samples || samples.length === 0) {
|
||||
return 0
|
||||
}
|
||||
|
||||
const sorted = [...samples].sort((a, b) => a - b)
|
||||
const index = Math.floor(sorted.length * 0.99)
|
||||
return sorted[index]
|
||||
}
|
||||
|
||||
getMax(operation: string): number {
|
||||
const samples = this.metrics.get(operation)
|
||||
if (!samples || samples.length === 0) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return Math.max(...samples)
|
||||
}
|
||||
|
||||
getMin(operation: string): number {
|
||||
const samples = this.metrics.get(operation)
|
||||
if (!samples || samples.length === 0) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return Math.min(...samples)
|
||||
}
|
||||
|
||||
getMetrics(): Record<string, any> {
|
||||
const result: Record<string, any> = {}
|
||||
|
||||
for (const [operation, samples] of this.metrics.entries()) {
|
||||
result[operation] = {
|
||||
average: this.getAverage(operation),
|
||||
p95: this.getP95(operation),
|
||||
p99: this.getP99(operation),
|
||||
max: this.getMax(operation),
|
||||
min: this.getMin(operation),
|
||||
count: samples.length
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
clearMetrics(): void {
|
||||
this.metrics.clear()
|
||||
}
|
||||
|
||||
clearOperationMetrics(operation: string): void {
|
||||
this.metrics.delete(operation)
|
||||
}
|
||||
|
||||
printReport(): void {
|
||||
console.log('========== 性能监控报告 ==========')
|
||||
const metrics = this.getMetrics()
|
||||
|
||||
for (const [operation, data] of Object.entries(metrics)) {
|
||||
console.log(`\n${operation}:`)
|
||||
console.log(` 平均耗时: ${data.average.toFixed(2)}ms`)
|
||||
console.log(` P95耗时: ${data.p95.toFixed(2)}ms`)
|
||||
console.log(` P99耗时: ${data.p99.toFixed(2)}ms`)
|
||||
console.log(` 最大耗时: ${data.max.toFixed(2)}ms`)
|
||||
console.log(` 最小耗时: ${data.min.toFixed(2)}ms`)
|
||||
console.log(` 采样次数: ${data.count}`)
|
||||
}
|
||||
|
||||
console.log('==================================')
|
||||
}
|
||||
}
|
||||
|
||||
const performanceMonitor = new PerformanceMonitor()
|
||||
|
||||
export default performanceMonitor
|
||||
Reference in New Issue
Block a user