第一次用windsurf,确实好用

之前看到你们搞cursor都没用过,现在试了试windsurf,确实好用。

import platform
import psutil
import dash
from dash import html, dcc
from dash.dependencies import Input, Output, State
import dash_bootstrap_components as dbc
from datetime import datetime
import time
from collections import deque
from functools import lru_cache
import GPUtil
import os
import cpuinfo
import getpass
from dash.exceptions import PreventUpdate
import plotly.graph_objects as go

print("正在初始化系统监控程序...")

# 性能优化:初始化数据存储和缓存
last_update = time.time()
last_net_io = None

# 初始化时间序列数据
TIME_SERIES_LENGTH = 180  # 30分钟,每10秒一个点
network_times = deque(maxlen=TIME_SERIES_LENGTH)
network_sent = deque(maxlen=TIME_SERIES_LENGTH)
network_recv = deque(maxlen=TIME_SERIES_LENGTH)

# 初始化应用
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.LITERA])
app.title = "Windows 系统监控"

# 更新间隔(毫秒)
UPDATE_INTERVAL = 10000  # 10秒
CACHE_TIMEOUT = 10  # 缓存10秒

# 缓存装饰器
def cache_with_timeout(timeout):
    def decorator(func):
        last_call = {'time': 0, 'result': None}
        
        def wrapper(*args, **kwargs):
            current_time = time.time()
            if current_time - last_call['time'] < timeout:
                return last_call['result']
            
            result = func(*args, **kwargs)
            last_call['result'] = result
            last_call['time'] = current_time
            return result
        
        return wrapper
    return decorator

# 性能优化:初始化数据存储
cpu_times = deque(maxlen=TIME_SERIES_LENGTH)
cpu_percentages = deque(maxlen=TIME_SERIES_LENGTH)
memory_times = deque(maxlen=TIME_SERIES_LENGTH)
memory_percentages = deque(maxlen=TIME_SERIES_LENGTH)
gpu_times = {}  # 每个GPU一个时间序列
gpu_loads = {}  # 每个GPU的负载历史
gpu_memory_usages = {}  # 每个GPU的显存使用历史

def initialize_gpu_queues():
    """初始化GPU数据队列"""
    try:
        gpus = GPUtil.getGPUs()
        for gpu in gpus:
            gpu_id = f"GPU_{gpu.id}"
            if gpu_id not in gpu_times:
                gpu_times[gpu_id] = deque(maxlen=TIME_SERIES_LENGTH)
                gpu_loads[gpu_id] = deque(maxlen=TIME_SERIES_LENGTH)
                gpu_memory_usages[gpu_id] = deque(maxlen=TIME_SERIES_LENGTH)
    except Exception as e:
        print(f"初始化GPU队列时出错: {e}")

# 初始化GPU队列
initialize_gpu_queues()

# 图表主题配置
chart_theme = {
    'plot_bgcolor': 'rgba(0,0,0,0)',
    'paper_bgcolor': 'rgba(0,0,0,0)',
    'font': {
        'family': 'system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
        'color': '#2c3e50',
        'size': 12
    },
    'xaxis': {
        'gridcolor': '#edf2f7',
        'linecolor': '#edf2f7',
        'tickfont': {'size': 10},
        'showgrid': True
    },
    'yaxis': {
        'gridcolor': '#edf2f7',
        'linecolor': '#edf2f7',
        'tickfont': {'size': 10},
        'showgrid': True
    },
    'margin': {'l': 40, 'r': 20, 't': 40, 'b': 40},
    'hovermode': 'x unified',
    'showlegend': True,
    'legend': {'orientation': 'h', 'y': -0.2}
}

def get_disk_info():
    """获取磁盘信息"""
    disk_info = []
    for partition in psutil.disk_partitions():
        try:
            usage = psutil.disk_usage(partition.mountpoint)
            disk_info.append({
                'device': partition.device,
                'mountpoint': partition.mountpoint,
                'fstype': partition.fstype,
                'total': usage.total,
                'used': usage.used,
                'free': usage.free,
                'percent': usage.percent
            })
        except Exception as e:
            print(f"获取磁盘信息错误 {partition.device}: {e}")
    return disk_info

def get_gpu_info():
    """获取GPU信息"""
    try:
        gpus = GPUtil.getGPUs()
        gpu_info = []
        current_time = datetime.now()
        
        for gpu in gpus:
            gpu_id = f"GPU_{gpu.id}"
            # 更新历史数据
            gpu_times[gpu_id].append(current_time)
            gpu_loads[gpu_id].append(gpu.load * 100)
            gpu_memory_usages[gpu_id].append(gpu.memoryUtil * 100)
            
            gpu_info.append({
                'id': gpu.id,
                'name': gpu.name,
                'load': gpu.load * 100,
                'memory_total': gpu.memoryTotal,
                'memory_used': gpu.memoryUsed,
                'memory_free': gpu.memoryFree,
                'temperature': gpu.temperature,
                'memory_util': gpu.memoryUtil * 100
            })
        return gpu_info
    except Exception as e:
        print(f"获取GPU信息错误: {e}")
        return None

def get_progress_color(percent):
    """根据百分比返回合适的颜色"""
    if percent >= 90:
        return "linear-gradient(45deg, #ef4444, #dc2626)"  # 红色渐变
    elif percent >= 70:
        return "linear-gradient(45deg, #f59e0b, #d97706)"  # 黄色渐变
    elif percent >= 50:
        return "linear-gradient(45deg, #3b82f6, #2563eb)"  # 蓝色渐变
    else:
        return "linear-gradient(45deg, #22c55e, #16a34a)"  # 绿色渐变

@cache_with_timeout(CACHE_TIMEOUT)
def get_system_info():
    """获取系统信息"""
    try:
        cpu_info = cpuinfo.get_cpu_info()
        memory = psutil.virtual_memory()
        disk = psutil.disk_usage('/')
        
        return dbc.Card([
            dbc.CardBody([
                html.H4([
                    html.I(className="fas fa-microchip me-2"),
                    "系统信息"
                ], className="card-title text-primary d-flex align-items-center"),
                dbc.Row([
                    dbc.Col([
                        dbc.ListGroup([
                            dbc.ListGroupItem([
                                html.I(className="fas fa-desktop me-2"),
                                html.Strong("操作系统: "),
                                html.Span(f"{platform.system()} {platform.release()}")
                            ], className="d-flex align-items-center"),
                            dbc.ListGroupItem([
                                html.I(className="fas fa-microchip me-2"),
                                html.Strong("处理器: "),
                                html.Span(cpu_info['brand_raw'])
                            ], className="d-flex align-items-center"),
                            dbc.ListGroupItem([
                                html.I(className="fas fa-cogs me-2"),
                                html.Strong("CPU架构: "),
                                html.Span(f"{cpu_info['arch']} ({cpu_info['bits']}位)")
                            ], className="d-flex align-items-center"),
                            dbc.ListGroupItem([
                                html.I(className="fas fa-memory me-2"),
                                html.Strong("内存大小: "),
                                html.Span(f"{memory.total / (1024**3):.1f} GB")
                            ], className="d-flex align-items-center"),
                        ], flush=True)
                    ], width=6),
                    dbc.Col([
                        dbc.ListGroup([
                            dbc.ListGroupItem([
                                html.I(className="fas fa-hdd me-2"),
                                html.Strong("系统盘容量: "),
                                html.Span(f"{disk.total / (1024**3):.1f} GB")
                            ], className="d-flex align-items-center"),
                            dbc.ListGroupItem([
                                html.I(className="fas fa-clock me-2"),
                                html.Strong("系统启动时间: "),
                                html.Span(f"{datetime.fromtimestamp(psutil.boot_time()).strftime('%Y-%m-%d %H:%M:%S')}")
                            ], className="d-flex align-items-center"),
                            dbc.ListGroupItem([
                                html.I(className="fas fa-network-wired me-2"),
                                html.Strong("主机名: "),
                                html.Span(platform.node())
                            ], className="d-flex align-items-center"),
                            dbc.ListGroupItem([
                                html.I(className="fas fa-user me-2"),
                                html.Strong("当前用户: "),
                                html.Span(getpass.getuser())
                            ], className="d-flex align-items-center"),
                        ], flush=True)
                    ], width=6),
                ])
            ])
        ], className="mb-4 system-info-card")
    except Exception as e:
        print(f"获取系统信息错误: {e}")
        return dbc.Card(dbc.CardBody([html.P("获取系统信息失败")]))

@cache_with_timeout(CACHE_TIMEOUT)
def get_resource_info():
    """获取资源使用情况"""
    try:
        # CPU信息 - 使用0.1秒的采样间隔以获得更准确的值
        cpu_percent = psutil.cpu_percent(interval=0.1)
        cpu_times.append(datetime.now())
        cpu_percentages.append(cpu_percent)
        
        # CPU核心信息 - 同样使用0.1秒的采样间隔
        cpu_percents = psutil.cpu_percent(interval=0.1, percpu=True)
        
        # 内存信息
        memory = psutil.virtual_memory()
        swap = psutil.swap_memory()
        
        # 添加内存历史数据
        memory_times.append(datetime.now())
        memory_percentages.append(memory.percent)
        
        # 更新网络速度数据
        get_network_speed()
        
        # GPU信息
        gpu_info = get_gpu_info()
        
        # 磁盘信息
        disk_info = get_disk_info()
        
        # CPU使用率图表
        cpu_graph = dcc.Graph(
            figure={
                'data': [
                    go.Scatter(
                        x=list(cpu_times),
                        y=list(cpu_percentages),
                        name='CPU使用率',
                        fill='tozeroy',
                        line=dict(color='#3498db')
                    )
                ],
                'layout': {
                    **chart_theme,
                    'title': 'CPU使用率历史',
                    'xaxis': {'title': '时间'},
                    'yaxis': {'title': '使用率 (%)', 'range': [0, 100]},
                    'margin': {'l': 50, 'r': 20, 't': 40, 'b': 50},
                    'showlegend': False
                }
            },
            config={'displayModeBar': False},
            className="shadow-sm"
        )
        
        # 内存使用率图表
        memory_graph = dcc.Graph(
            figure={
                'data': [
                    go.Scatter(
                        x=list(memory_times),
                        y=list(memory_percentages),
                        name='内存使用率',
                        fill='tozeroy',
                        line=dict(color='#2ecc71')
                    )
                ],
                'layout': {
                    **chart_theme,
                    'title': '内存使用率历史',
                    'xaxis': {'title': '时间'},
                    'yaxis': {'title': '使用率 (%)', 'range': [0, 100]},
                    'margin': {'l': 50, 'r': 20, 't': 40, 'b': 50},
                    'showlegend': False
                }
            },
            config={'displayModeBar': False},
            className="shadow-sm"
        )
        
        # CPU核心使用率表格
        cores_table = dbc.Table(
            [
                html.Thead(
                    html.Tr([
                        html.Th("CPU核心", style={'width': '30%'}),
                        html.Th("使用率", style={'width': '70%'})
                    ]), 
                    className="table-light"
                ),
                html.Tbody([
                    html.Tr([
                        html.Td(f"核心 {i}"),
                        html.Td([
                            html.Div(
                                className="progress",
                                children=[
                                    html.Div(
                                        className="progress-bar",
                                        style={
                                            "width": f"{percent}%",
                                            "backgroundColor": "#007bff"
                                        },
                                        children=[
                                            html.Span(
                                                f"{percent:.1f}%",
                                                className="progress-text"
                                            )
                                        ]
                                    )
                                ]
                            )
                        ])
                    ]) for i, percent in enumerate(cpu_percents)
                ])
            ],
            bordered=True,
            hover=True,
            responsive=True,
            striped=True,
            className="mt-3"
        )
        
        # 磁盘使用率表格
        disk_table = dbc.Table(
            [
                html.Thead(
                    html.Tr([
                        html.Th("盘符"),
                        html.Th("总容量"),
                        html.Th("已用空间"),
                        html.Th("使用率")
                    ]), 
                    className="table-light"
                ),
                html.Tbody([
                    html.Tr([
                        html.Td(f"{disk['mountpoint']}"),
                        html.Td(f"{disk['total'] / (1024**3):.1f} GB"),
                        html.Td(f"{disk['used'] / (1024**3):.1f} GB"),
                        html.Td([
                            html.Div(
                                className="progress",
                                children=[
                                    html.Div(
                                        className="progress-bar",
                                        style={
                                            "width": f"{disk['percent']}%",
                                            "backgroundColor": "#007bff"
                                        },
                                        children=[
                                            html.Span(
                                                f"{disk['percent']:.1f}%",
                                                className="progress-text"
                                            )
                                        ]
                                    )
                                ]
                            )
                        ])
                    ]) for disk in disk_info
                ])
            ],
            bordered=True,
            hover=True,
            responsive=True,
            striped=True,
            className="mt-3"
        )
        
        # 网络速度图表
        network_graph = dcc.Graph(
            figure={
                'data': [
                    go.Scatter(
                        x=list(network_times),
                        y=list(network_sent),
                        name='上传速度',
                        line=dict(color='#e67e22')
                    ),
                    go.Scatter(
                        x=list(network_times),
                        y=list(network_recv),
                        name='下载速度',
                        line=dict(color='#27ae60')
                    )
                ],
                'layout': {
                    **chart_theme,
                    'title': '网络速度历史',
                    'xaxis': {'title': '时间'},
                    'yaxis': {'title': '速度 (MB/s)'},
                    'margin': {'l': 50, 'r': 20, 't': 40, 'b': 50},
                    'showlegend': True,
                    'legend': {'orientation': 'h', 'y': -0.2}
                }
            },
            config={'displayModeBar': False},
            className="shadow-sm"
        )
        
        # GPU信息和图表
        if gpu_info:
            gpu_cards = []
            for gpu in gpu_info:
                gpu_id = f"GPU_{gpu['id']}"
                # GPU使用率历史图表
                gpu_load_graph = dcc.Graph(
                    figure={
                        'data': [
                            go.Scatter(
                                x=list(gpu_times[gpu_id]),
                                y=list(gpu_loads[gpu_id]),
                                name='GPU使用率',
                                fill='tozeroy',
                                line=dict(color='#e74c3c')
                            )
                        ],
                        'layout': {
                            **chart_theme,
                            'title': f'GPU {gpu["id"]} 使用率历史',
                            'xaxis': {'title': '时间'},
                            'yaxis': {'title': '使用率 (%)', 'range': [0, 100]},
                            'margin': {'l': 50, 'r': 20, 't': 40, 'b': 50},
                            'showlegend': False
                        }
                    },
                    config={'displayModeBar': False},
                    className="shadow-sm"
                )
                
                # GPU显存使用率历史图表
                gpu_memory_graph = dcc.Graph(
                    figure={
                        'data': [
                            go.Scatter(
                                x=list(gpu_times[gpu_id]),
                                y=list(gpu_memory_usages[gpu_id]),
                                name='显存使用率',
                                fill='tozeroy',
                                line=dict(color='#9b59b6')
                            )
                        ],
                        'layout': {
                            **chart_theme,
                            'title': f'GPU {gpu["id"]} 显存使用率历史',
                            'xaxis': {'title': '时间'},
                            'yaxis': {'title': '使用率 (%)', 'range': [0, 100]},
                            'margin': {'l': 50, 'r': 20, 't': 40, 'b': 50},
                            'showlegend': False
                        }
                    },
                    config={'displayModeBar': False},
                    className="shadow-sm"
                )
                
                gpu_cards.append(
                    dbc.ListGroupItem([
                        html.Strong(f"GPU {gpu['id']}: {gpu['name']}"),
                        html.Div([
                            html.Div([
                                html.Strong("总显存: "),
                                html.Span(f"{gpu['memory_total']:.1f} MB")
                            ]),
                            html.Div([
                                html.Strong("已用显存: "),
                                html.Span(f"{gpu['memory_used']:.1f} MB")
                            ]),
                            html.Div([
                                html.Strong("温度: "),
                                html.Span(f"{gpu['temperature']:.1f}°C")
                            ]),
                            html.Div([
                                html.Strong("GPU使用率:"),
                                html.Div(
                                    className="progress",
                                    children=[
                                        html.Div(
                                            className="progress-bar",
                                            style={
                                                "width": f"{gpu['load']}%",
                                                "backgroundColor": "#007bff"
                                            },
                                            children=[
                                                html.Span(
                                                    f"{gpu['load']:.1f}%",
                                                    className="progress-text"
                                                )
                                            ]
                                        )
                                    ]
                                )
                            ]),
                            html.Div([
                                html.Strong("显存使用率:"),
                                html.Div(
                                    className="progress",
                                    children=[
                                        html.Div(
                                            className="progress-bar",
                                            style={
                                                "width": f"{gpu['memory_util']}%",
                                                "backgroundColor": "#007bff"
                                            },
                                            children=[
                                                html.Span(
                                                    f"{gpu['memory_util']:.1f}%",
                                                    className="progress-text"
                                                )
                                            ]
                                        )
                                    ]
                                )
                            ]),
                            html.Div([
                                dbc.Row([
                                    dbc.Col([gpu_load_graph], width=12, className="mb-4"),
                                    dbc.Col([gpu_memory_graph], width=12, className="mb-4")
                                ])
                            ])
                        ])
                    ], className="border-0")
                )
            
            memory_items = [
                dbc.ListGroupItem([
                    html.Strong("物理内存"),
                    html.Div([
                        html.Div([
                            html.Strong("总内存: "),
                            html.Span(f"{memory.total / (1024**3):.1f} GB")
                        ]),
                        html.Div([
                            html.Strong("已用内存: "),
                            html.Span(f"{(memory.total - memory.available) / (1024**3):.1f} GB")
                        ]),
                        html.Div([
                            html.Strong("可用内存: "),
                            html.Span(f"{memory.available / (1024**3):.1f} GB")
                        ]),
                        html.Div([
                            html.Div(
                                className="progress",
                                children=[
                                    html.Div(
                                        className="progress-bar",
                                        style={
                                            "width": f"{memory.percent}%",
                                            "backgroundColor": "#007bff"
                                        },
                                        children=[
                                            html.Span(
                                                f"{memory.percent}%",
                                                className="progress-text"
                                            )
                                        ]
                                    )
                                ]
                            )
                        ])
                    ])
                ], className="border-0"),
                dbc.ListGroupItem([
                    html.Strong("虚拟内存"),
                    html.Div([
                        html.Div([
                            html.Strong("总大小: "),
                            html.Span(f"{swap.total / (1024**3):.1f} GB")
                        ]),
                        html.Div([
                            html.Strong("已用空间: "),
                            html.Span(f"{swap.used / (1024**3):.1f} GB")
                        ]),
                        html.Div([
                            html.Strong("可用空间: "),
                            html.Span(f"{swap.free / (1024**3):.1f} GB")
                        ]),
                        html.Div([
                            html.Div(
                                className="progress",
                                children=[
                                    html.Div(
                                        className="progress-bar",
                                        style={
                                            "width": f"{swap.percent}%",
                                            "backgroundColor": "#007bff"
                                        },
                                        children=[
                                            html.Span(
                                                f"{swap.percent}%",
                                                className="progress-text"
                                            )
                                        ]
                                    )
                                ]
                            )
                        ])
                    ])
                ], className="border-0")
            ]
            
            # 如果有GPU信息,添加到列表中
            memory_items.extend(gpu_cards)
        
            return dbc.Card([
                dbc.CardBody([
                    html.H4("系统资源使用情况", className="card-title text-primary"),
                    dbc.Row([
                        dbc.Col([
                            dbc.ListGroup(memory_items, flush=True)
                        ], md=12, lg=4),
                        dbc.Col([
                            dbc.Row([
                                dbc.Col([cpu_graph], width=12, className="mb-4"),
                                dbc.Col([memory_graph], width=12, className="mb-4"),
                                dbc.Col([network_graph], width=12, className="mb-4"),
                                dbc.Col([
                                    html.H5("CPU核心使用率", className="mt-2 text-primary"),
                                    cores_table
                                ], width=12, className="mb-4"),
                                dbc.Col([
                                    html.H5("磁盘使用情况", className="mt-2 text-primary"),
                                    disk_table
                                ], width=12, className="mb-4")
                            ])
                        ], md=12, lg=8)
                    ])
                ])
            ], className="mb-4 shadow-sm")
        else:
            return dbc.Card([
                dbc.CardBody([
                    html.H4("系统资源使用情况", className="card-title text-primary"),
                    dbc.Row([
                        dbc.Col([
                            dbc.ListGroup(memory_items, flush=True)
                        ], md=12, lg=4),
                        dbc.Col([
                            dbc.Row([
                                dbc.Col([cpu_graph], width=12, className="mb-4"),
                                dbc.Col([memory_graph], width=12, className="mb-4"),
                                dbc.Col([network_graph], width=12, className="mb-4"),
                                dbc.Col([
                                    html.H5("CPU核心使用率", className="mt-2 text-primary"),
                                    cores_table
                                ], width=12, className="mb-4"),
                                dbc.Col([
                                    html.H5("磁盘使用情况", className="mt-2 text-primary"),
                                    disk_table
                                ], width=12, className="mb-4")
                            ])
                        ], md=12, lg=8)
                    ])
                ])
            ], className="mb-4 shadow-sm")
    except Exception as e:
        print(f"获取资源信息错误: {e}")
        return dbc.Card(dbc.CardBody([html.P("获取资源信息失败")]))

@cache_with_timeout(CACHE_TIMEOUT)
def get_process_info():
    """获取进程信息"""
    try:
        processes = []
        cpu_count = psutil.cpu_count()  # 获取CPU核心数
        
        for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent', 'status']):
            try:
                # 获取进程信息
                pinfo = proc.info
                cpu_percent = pinfo['cpu_percent'] / cpu_count  # 将CPU使用率除以核心数
                if cpu_percent > 0:  # 只显示有CPU使用的进程
                    processes.append({
                        'pid': pinfo['pid'],
                        'name': pinfo['name'],
                        'cpu_percent': cpu_percent,
                        'memory_percent': pinfo.get('memory_percent', 0),
                        'status': pinfo['status']
                    })
            except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
                pass

        # 按CPU使用率排序并获取前20个进程
        processes.sort(key=lambda x: x['cpu_percent'], reverse=True)
        top_processes = processes[:20]

        # 创建进程表格
        table_header = [
            html.Thead(html.Tr([
                html.Th("PID", className="text-center"),
                html.Th("进程名", className="text-center"),
                html.Th("CPU使用率", className="text-center"),
                html.Th("内存使用率", className="text-center"),
                html.Th("状态", className="text-center")
            ]), className="table-light")
        ]

        table_body = []
        for proc in top_processes:
            status_class = {
                'running': 'success',
                'sleeping': 'info',
                'stopped': 'warning',
                'zombie': 'danger'
            }.get(proc['status'].lower(), 'secondary')

            row = html.Tr([
                html.Td(str(proc['pid']), className="text-center value-display"),
                html.Td(proc['name'], className="text-center"),
                html.Td([
                    html.Div(className="progress", style={"height": "20px"},
                        children=[
                            html.Div(
                                className="progress-bar",
                                style={
                                    "width": f"{min(proc['cpu_percent'], 100)}%",
                                    "backgroundColor": get_progress_color(proc['cpu_percent'])
                                },
                                children=f"{proc['cpu_percent']:.1f}%"
                            )
                        ]
                    )
                ], className="text-center"),
                html.Td([
                    html.Div(className="progress", style={"height": "20px"},
                        children=[
                            html.Div(
                                className="progress-bar",
                                style={
                                    "width": f"{min(proc['memory_percent'], 100)}%",
                                    "backgroundColor": get_progress_color(proc['memory_percent'])
                                },
                                children=f"{proc['memory_percent']:.1f}%"
                            )
                        ]
                    )
                ], className="text-center"),
                html.Td(
                    html.Span(
                        proc['status'].capitalize(),
                        className=f"badge bg-{status_class}"
                    ),
                    className="text-center"
                )
            ])
            table_body.append(row)

        table = dbc.Table(
            table_header + [html.Tbody(table_body)],
            bordered=True,
            hover=True,
            responsive=True,
            striped=True,
            className="mt-3 align-middle"
        )

        return dbc.Card([
            dbc.CardHeader([
                html.H4([
                    html.I(className="fas fa-microchip me-2"),
                    "进程信息"
                ], className="card-title mb-0 d-flex align-items-center"),
                html.Small("显示CPU使用率前20的进程", className="text-muted ms-2")
            ], className="d-flex align-items-center"),
            dbc.CardBody([table], className="p-0")
        ], className="process-card shadow-sm")

    except Exception as e:
        print(f"获取进程信息错误: {e}")
        return html.Div("无法获取进程信息")

def get_health_status():
    """获取系统健康状态"""
    try:
        cpu_percent = psutil.cpu_percent(interval=None)
        memory = psutil.virtual_memory()
        disk = psutil.disk_usage('/')
        
        # 定义健康状态阈值
        status = {
            'cpu': {
                'status': 'good' if cpu_percent < 70 else 'warning' if cpu_percent < 90 else 'danger',
                'value': cpu_percent
            },
            'memory': {
                'status': 'good' if memory.percent < 70 else 'warning' if memory.percent < 90 else 'danger',
                'value': memory.percent
            },
            'disk': {
                'status': 'good' if disk.percent < 70 else 'warning' if disk.percent < 90 else 'danger',
                'value': disk.percent
            }
        }
        
        # 确定整体状态
        if any(s['status'] == 'danger' for s in status.values()):
            overall = 'danger'
        elif any(s['status'] == 'warning' for s in status.values()):
            overall = 'warning'
        else:
            overall = 'good'
            
        status_colors = {
            'good': '#22c55e',
            'warning': '#f59e0b',
            'danger': '#ef4444'
        }
        
        return dbc.Card([
            dbc.CardBody([
                html.H4([
                    html.I(className="fas fa-heartbeat me-2"),
                    "系统健康状态"
                ], className="card-title text-primary d-flex align-items-center"),
                html.Div([
                    html.Div([
                        html.Span("系统状态:", className="me-2"),
                        html.Span(
                            "良好" if overall == 'good' else "警告" if overall == 'warning' else "危险",
                            className=f"badge rounded-pill bg-{overall}"
                        )
                    ], className="mb-3"),
                    dbc.Row([
                        dbc.Col([
                            html.Div([
                                html.I(className="fas fa-microchip me-2"),
                                "CPU负载",
                                html.Span(
                                    f"{status['cpu']['value']:.1f}%",
                                    className="float-end",
                                    style={"color": status_colors[status['cpu']['status']]}
                                )
                            ], className="d-flex justify-content-between align-items-center")
                        ], width=4),
                        dbc.Col([
                            html.Div([
                                html.I(className="fas fa-memory me-2"),
                                "内存使用",
                                html.Span(
                                    f"{status['memory']['value']:.1f}%",
                                    className="float-end",
                                    style={"color": status_colors[status['memory']['status']]}
                                )
                            ], className="d-flex justify-content-between align-items-center")
                        ], width=4),
                        dbc.Col([
                            html.Div([
                                html.I(className="fas fa-hdd me-2"),
                                "磁盘使用",
                                html.Span(
                                    f"{status['disk']['value']:.1f}%",
                                    className="float-end",
                                    style={"color": status_colors[status['disk']['status']]}
                                )
                            ], className="d-flex justify-content-between align-items-center")
                        ], width=4)
                    ])
                ], className="health-status-container")
            ])
        ], className="mb-4 health-status-card")
    except Exception as e:
        print(f"获取健康状态错误: {e}")
        return html.Div()

def get_network_speed():
    """获取网络速度"""
    global last_net_io
    try:
        net_io = psutil.net_io_counters()
        current_time = datetime.now()
        
        if last_net_io is not None and len(network_times) > 0:
            # 计算时间差(秒)
            time_diff = (current_time - network_times[-1]).total_seconds()
            if time_diff > 0:
                # 计算发送和接收速度(MB/s)
                sent_speed = (net_io.bytes_sent - last_net_io.bytes_sent) / (1024 * 1024 * time_diff)
                recv_speed = (net_io.bytes_recv - last_net_io.bytes_recv) / (1024 * 1024 * time_diff)
                
                # 保持队列长度
                if len(network_times) >= TIME_SERIES_LENGTH:
                    network_times.pop(0)
                    network_sent.pop(0)
                    network_recv.pop(0)
                
                network_times.append(current_time)
                network_sent.append(sent_speed)
                network_recv.append(recv_speed)
                
                # 返回当前速度值用于显示
                return sent_speed, recv_speed
        else:
            # 第一次运行,添加0值
            network_times.append(current_time)
            network_sent.append(0)
            network_recv.append(0)
            
        last_net_io = net_io
        return 0, 0
        
    except Exception as e:
        print(f"获取网络速度错误: {e}")
        return 0, 0

def format_speed(speed):
    """格式化网络速度显示"""
    if speed < 1:
        return f"{speed * 1024:.1f} KB/s"
    else:
        return f"{speed:.1f} MB/s"

# 定义布局
app.layout = dbc.Container([
    dbc.Row([
        dbc.Col([
            html.Div([
                html.H1([
                    html.I(className="fas fa-chart-line me-3"),
                    "Windows 系统监控"
                ], className="text-center mb-4 text-primary d-flex align-items-center justify-content-center"),
                html.Div(id='health-status', className="fade-in"),
                html.Div(id='system-info', className="fade-in"),
                html.Div(id='resource-info', className="fade-in"),
                html.Div(id='process-info', className="fade-in")
            ], className="py-4")
        ], width=12)
    ]),
    
    dcc.Interval(
        id='interval-component',
        interval=UPDATE_INTERVAL,
        n_intervals=0
    )
], fluid=True, className="pb-4")

# 添加自定义CSS
app.index_string = '''
<!DOCTYPE html>
<html>
    <head>
        {%metas%}
        <title>{%title%}</title>
        {%favicon%}
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
        <link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;500&display=swap" rel="stylesheet">
        {%css%}
        <style>
            :root {
                --primary-color: #4f46e5;
                --success-color: #22c55e;
                --warning-color: #f59e0b;
                --danger-color: #ef4444;
                --info-color: #3b82f6;
                --background-color: #f8fafc;
                --card-background: #ffffff;
                --text-primary: #1e293b;
                --text-secondary: #64748b;
            }

            body {
                background-color: var(--background-color);
                font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
                color: var(--text-primary);
            }

            .card {
                border: none;
                border-radius: 16px;
                background: var(--card-background);
                box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
                transition: all 0.3s ease;
                margin-bottom: 1.5rem;
            }

            .card:hover {
                transform: translateY(-2px);
                box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
            }

            .table {
                --bs-table-striped-bg: rgba(0, 0, 0, 0.02);
                margin-bottom: 0;
            }

            .table th {
                font-weight: 600;
                color: var(--text-secondary);
                border-bottom-width: 2px;
                padding: 1rem;
            }

            .table td {
                padding: 1rem;
                vertical-align: middle;
                color: var(--text-primary);
            }

            @keyframes fadeIn {
                from { opacity: 0; transform: translateY(20px); }
                to { opacity: 1; transform: translateY(0); }
            }

            .fade-in {
                animation: fadeIn 0.5s ease forwards;
            }

            .badge {
                padding: 0.5em 1em;
                font-weight: 500;
                border-radius: 9999px;
            }

            .badge.bg-success { background-color: var(--success-color) !important; }
            .badge.bg-warning { background-color: var(--warning-color) !important; }
            .badge.bg-danger { background-color: var(--danger-color) !important; }

            .value-display {
                font-family: 'Roboto Mono', monospace;
                font-weight: 500;
            }

            .card-header {
                background: transparent;
                border-bottom: 1px solid rgba(0, 0, 0, 0.05);
                padding: 1.25rem;
            }

            .card-body {
                padding: 1.25rem;
            }

            @media (max-width: 768px) {
                .container-fluid {
                    padding: 1rem;
                }
                
                .card {
                    margin-bottom: 1rem;
                }
                
                .table {
                    font-size: 0.875rem;
                }
                
                .badge {
                    font-size: 0.75rem;
                }
            }
        </style>
    </head>
    <body>
        {%app_entry%}
        <footer>
            {%config%}
            {%scripts%}
            {%renderer%}
        </footer>
    </body>
</html>
'''

# 性能优化:更新回调
@app.callback(
    [
        Output('health-status', 'children'),
        Output('system-info', 'children'),
        Output('resource-info', 'children'),
        Output('process-info', 'children')
    ],
    [Input('interval-component', 'n_intervals')]
)
def update_metrics(n):
    """更新所有指标"""
    try:
        return (
            get_health_status(),
            get_system_info(),
            get_resource_info(),
            get_process_info()
        )
    except Exception as e:
        print(f"更新指标错误: {e}")
        return (
            html.Div("系统健康状态获取失败"),
            html.Div("系统信息获取失败"),
            html.Div("资源信息获取失败"),
            html.Div("进程信息获取失败")
        )

if __name__ == '__main__':
    print("\n正在启动服务器...")
    app.run_server(debug=False)

非实用程序,只是试试水。

12 Likes

cursor用过,没用过 windsurf

我两个都有用,都挺好用的。

太强了,大佬


大佬们,我这是怎么回事

今天体验了下,还可以。 让他自动来段Python开发个网站。基本上错误很少。