# 监控与日志

<cite>
**本文引用的文件**
- [src/log.ts](file://src/log.ts)
- [src/index.ts](file://src/index.ts)
- [src/server.ts](file://src/server.ts)
- [src/class/options.ts](file://src/class/options.ts)
- [src/class/httphandler.ts](file://src/class/httphandler.ts)
- [src/class/websockethandler.ts](file://src/class/websockethandler.ts)
- [src/websocket.ts](file://src/websocket.ts)
- [src/signaling.ts](file://src/signaling.ts)
- [src/swagger.ts](file://src/swagger.ts)
- [client/src/logger.js](file://client/src/logger.js)
- [client/public/js/stats.js](file://client/public/js/stats.js)
- [package.json](file://package.json)
- [run.bat](file://run.bat)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本指南聚焦于视频信令服务器的监控与日志配置，覆盖以下方面：
- 日志系统配置：日志级别、输出格式与时序、HTTP访问日志策略
- 性能监控指标：连接数统计、内存使用、请求响应时间与错误率
- 分布式追踪：请求链路跟踪与性能瓶颈定位思路
- 告警规则：阈值设定、通知渠道与故障恢复建议
- 工具集成：Prometheus、Grafana、ELK Stack 的对接要点
- 日志分析与故障诊断：常见问题与监控解决方案

## 项目结构
该项目采用分层与职责分离的设计：
- 应用入口负责解析命令行参数、创建HTTP/HTTPS服务器、启动WebSocket信令服务
- Express服务器负责HTTP路由、静态资源、Swagger文档与HTTP信令接口
- WebSocket服务器负责实时信令消息的收发与连接生命周期管理
- 日志模块提供统一的日志级别控制与格式化输出
- 客户端侧提供前端调试日志开关与媒体统计展示

```mermaid
graph TB
A["应用入口<br/>src/index.ts"] --> B["Express服务器<br/>src/server.ts"]
A --> C["WebSocket信令<br/>src/websocket.ts"]
B --> D["HTTP信令路由<br/>src/signaling.ts"]
D --> E["HTTP处理器<br/>src/class/httphandler.ts"]
C --> F["WebSocket处理器<br/>src/class/websockethandler.ts"]
A --> G["日志模块<br/>src/log.ts"]
B --> H["Swagger文档<br/>src/swagger.ts"]
I["客户端调试日志<br/>client/src/logger.js"] -.-> A
```

**图表来源**
- [src/index.ts:13-108](file://src/index.ts#L13-L108)
- [src/server.ts:14-89](file://src/server.ts#L14-L89)
- [src/websocket.ts:6-117](file://src/websocket.ts#L6-L117)
- [src/signaling.ts:1-24](file://src/signaling.ts#L1-L24)
- [src/class/httphandler.ts:1-120](file://src/class/httphandler.ts#L1-L120)
- [src/class/websockethandler.ts:1-66](file://src/class/websockethandler.ts#L1-L66)
- [src/log.ts:1-51](file://src/log.ts#L1-L51)
- [src/swagger.ts:16-65](file://src/swagger.ts#L16-L65)
- [client/src/logger.js:1-30](file://client/src/logger.js#L1-L30)

**章节来源**
- [src/index.ts:13-108](file://src/index.ts#L13-L108)
- [src/server.ts:14-89](file://src/server.ts#L14-L89)
- [src/websocket.ts:6-117](file://src/websocket.ts#L6-L117)
- [src/signaling.ts:1-24](file://src/signaling.ts#L1-L24)
- [src/class/httphandler.ts:1-120](file://src/class/httphandler.ts#L1-L120)
- [src/class/websockethandler.ts:1-66](file://src/class/websockethandler.ts#L1-L66)
- [src/log.ts:1-51](file://src/log.ts#L1-L51)
- [src/swagger.ts:16-65](file://src/swagger.ts#L16-L65)
- [client/src/logger.js:1-30](file://client/src/logger.js#L1-L30)

## 核心组件
- 日志模块：提供日志级别枚举、动态级别设置、时间戳格式化与不同级别输出
- HTTP服务器：基于Express，启用Morgan进行HTTP访问日志，支持多种格式
- WebSocket信令：基于ws，维护连接组、广播与心跳检测
- HTTP信令处理器：基于会话与连接ID管理，提供offer/answer/candidate等信令存取
- Swagger文档：自动生成API文档，便于监控与排障时查阅接口规范

**章节来源**
- [src/log.ts:1-51](file://src/log.ts#L1-L51)
- [src/server.ts:14-89](file://src/server.ts#L14-L89)
- [src/websocket.ts:6-117](file://src/websocket.ts#L6-L117)
- [src/class/httphandler.ts:1-120](file://src/class/httphandler.ts#L1-L120)
- [src/class/websockethandler.ts:1-66](file://src/class/websockethandler.ts#L1-L66)
- [src/swagger.ts:16-65](file://src/swagger.ts#L16-L65)

## 架构总览
下图展示了从请求进入、HTTP处理、WebSocket处理到日志输出的整体流程。

```mermaid
sequenceDiagram
participant Client as "客户端"
participant HTTP as "HTTP服务器<br/>src/server.ts"
participant Sig as "HTTP信令路由<br/>src/signaling.ts"
participant Hdl as "HTTP处理器<br/>src/class/httphandler.ts"
participant WS as "WebSocket服务器<br/>src/websocket.ts"
participant WSH as "WebSocket处理器<br/>src/class/websockethandler.ts"
participant Log as "日志模块<br/>src/log.ts"
Client->>HTTP : "HTTP请求"
HTTP->>Sig : "路由到/signaling"
Sig->>Hdl : "调用处理器(如创建会话/获取offer)"
Hdl-->>HTTP : "响应(200/4xx)"
HTTP-->>Client : "HTTP响应"
Client->>WS : "WebSocket连接"
WS->>WSH : "on('connection')"
WSH-->>Log : "记录连接/断开/消息"
WSH-->>Client : "信令消息(offer/answer/candidate)"
```

**图表来源**
- [src/server.ts:14-89](file://src/server.ts#L14-L89)
- [src/signaling.ts:1-24](file://src/signaling.ts#L1-L24)
- [src/class/httphandler.ts:398-641](file://src/class/httphandler.ts#L398-L641)
- [src/websocket.ts:27-115](file://src/websocket.ts#L27-L115)
- [src/class/websockethandler.ts:145-206](file://src/class/websockethandler.ts#L145-L206)
- [src/log.ts:30-50](file://src/log.ts#L30-L50)

## 详细组件分析

### 日志系统配置
- 日志级别
  - 支持 none/error/warn/log/info 五级，可通过运行参数或环境变量设置
  - 默认级别为 info；当级别为 none 时不输出任何日志
- 输出格式
  - 自动添加ISO时间戳与大写的级别前缀
  - 使用不同console方法区分 error/warn/info/log
- HTTP访问日志
  - 通过 Morgan 中间件启用，支持 combined/dev/short/tiny 或禁用
  - 日志级别与Morgan日志可并行使用，便于区分业务日志与访问日志

```mermaid
flowchart TD
Start(["设置日志级别"]) --> Parse["解析字符串级别<br/>parseLogLevel()"]
Parse --> Set["setLogLevel() 更新全局级别"]
Set --> Check{"当前级别是否允许输出？"}
Check --> |否| Exit["直接返回"]
Check --> |是| Format["formatTimestamp()<br/>拼装前缀"]
Format --> Emit{"根据级别选择输出方法"}
Emit --> Console["console.error/warn/info/log"]
Console --> End(["完成"])
```

**图表来源**
- [src/log.ts:11-24](file://src/log.ts#L11-L24)
- [src/log.ts:26-50](file://src/log.ts#L26-L50)

**章节来源**
- [src/log.ts:1-51](file://src/log.ts#L1-L51)
- [src/server.ts:18-20](file://src/server.ts#L18-L20)
- [src/index.ts:28](file://src/index.ts#L28)
- [package.json:9](file://package.json#L9)
- [run.bat:8](file://run.bat#L8)

### HTTP访问日志与路由
- 访问日志
  - 通过 Morgan 中间件以配置项启用，支持多种格式
  - 可通过运行参数控制，避免生产环境产生过多日志
- 信令路由
  - 提供会话创建、连接管理、offer/answer/candidate获取与推送
  - 使用会话ID作为安全约束，确保接口访问受控

```mermaid
sequenceDiagram
participant Client as "客户端"
participant Server as "Express服务器"
participant Router as "HTTP信令路由"
participant Handler as "HTTP处理器"
Client->>Server : "GET /signaling/connection"
Server->>Router : "匹配路由"
Router->>Handler : "checkSessionId() 校验"
Handler-->>Router : "返回连接列表"
Router-->>Server : "JSON响应"
Server-->>Client : "HTTP 200"
```

**图表来源**
- [src/server.ts:25-86](file://src/server.ts#L25-L86)
- [src/signaling.ts:6-24](file://src/signaling.ts#L6-L24)
- [src/class/httphandler.ts:128-145](file://src/class/httphandler.ts#L128-L145)

**章节来源**
- [src/server.ts:14-89](file://src/server.ts#L14-L89)
- [src/signaling.ts:1-24](file://src/signaling.ts#L1-L24)
- [src/class/httphandler.ts:128-145](file://src/class/httphandler.ts#L128-L145)

### WebSocket信令与连接管理
- 连接生命周期
  - 建立连接时注册，断开时清理；记录连接/断开/消息等事件
- 1对多模式
  - host与participants角色分工，offer/answer/candidate按角色路由
  - 支持广播与定向消息，便于扩展聊天、白板等场景
- 心跳与超时
  - 定期发送ping并检查lastActivity，超时自动断开，降低僵尸连接占用

```mermaid
classDiagram
class WSSignaling {
+server
+wss
+constructor(server, mode)
}
class WebSocketHandler {
+reset(mode)
+add(ws)
+remove(ws)
+onConnect(ws, connectionId)
+onDisconnect(ws, connectionId)
+onOffer(ws, message)
+onAnswer(ws, message)
+onCandidate(ws, message)
+onBroadcast(ws, message)
+onMessage(ws, message)
+AddHeartbeat(ws, connectionId)
+RemoveHeartbeat(ws)
}
WSSignaling --> WebSocketHandler : "委托处理"
```

**图表来源**
- [src/websocket.ts:15-117](file://src/websocket.ts#L15-L117)
- [src/class/websockethandler.ts:63-479](file://src/class/websockethandler.ts#L63-L479)

**章节来源**
- [src/websocket.ts:6-117](file://src/websocket.ts#L6-L117)
- [src/class/websockethandler.ts:145-338](file://src/class/websockethandler.ts#L145-L338)

### HTTP处理器与会话/连接模型
- 会话与连接
  - 会话ID唯一标识一次通话或交互；连接ID标识具体端点
  - 支持私有模式下的双向配对与公共模式下的广播
- 信令存储
  - offer/answer/candidate按连接ID与会话ID存储，支持按时间过滤
- 超时与清理
  - 基于lastRequestedTime定期清理超时会话，释放资源

```mermaid
flowchart TD
S["创建会话(createSession)"] --> C["创建连接(createConnection)"]
C --> O["接收/存储offer"]
C --> A["接收/存储answer"]
C --> K["接收/存储candidate"]
O --> R["按fromtime过滤返回(getOffer)"]
A --> R2["按fromtime过滤返回(getAnswer)"]
K --> R3["按fromtime过滤返回(getCandidate)"]
T["超时检测(_checkForTimedOutSessions)"] --> Del["删除会话(_deleteSession)"]
```

**图表来源**
- [src/class/httphandler.ts:664-675](file://src/class/httphandler.ts#L664-L675)
- [src/class/httphandler.ts:739-783](file://src/class/httphandler.ts#L739-L783)
- [src/class/httphandler.ts:218-232](file://src/class/httphandler.ts#L218-L232)
- [src/class/httphandler.ts:200-213](file://src/class/httphandler.ts#L200-L213)

**章节来源**
- [src/class/httphandler.ts:106-120](file://src/class/httphandler.ts#L106-L120)
- [src/class/httphandler.ts:218-232](file://src/class/httphandler.ts#L218-L232)
- [src/class/httphandler.ts:398-641](file://src/class/httphandler.ts#L398-L641)

### 客户端日志与媒体统计
- 客户端调试日志
  - 提供enable/disable与多级别输出，便于前端问题定位
- 媒体统计
  - 基于RTCStats计算比特率、帧率等指标，辅助性能分析

**章节来源**
- [client/src/logger.js:1-30](file://client/src/logger.js#L1-L30)
- [client/public/js/stats.js:7-91](file://client/public/js/stats.js#L7-L91)

## 依赖关系分析
- 运行时依赖
  - Express、ws、morgan、swagger-ui-express、uuid等
- 开发与测试
  - Jest、ts-jest、mock-socket等
- 构建与打包
  - TypeScript编译、pkg打包静态资源

```mermaid
graph LR
P["package.json"] --> E["express"]
P --> W["ws"]
P --> M["morgan"]
P --> S["swagger-ui-express"]
P --> U["uuid"]
P --> J["jest/ts-jest"]
P --> T["typescript"]
```

**图表来源**
- [package.json:14-46](file://package.json#L14-L46)

**章节来源**
- [package.json:14-46](file://package.json#L14-L46)

## 性能考量
- 连接数统计
  - WebSocket侧：通过连接集合与连接组统计当前活跃连接数
  - HTTP侧：通过会话与连接映射统计会话数量与连接数
- 内存使用
  - 信令消息以Map/Set存储，需关注超时清理与消息大小
  - 前端媒体统计可辅助判断网络拥塞与编码开销
- 请求响应时间与错误率
  - HTTP接口响应时间可通过中间件埋点或外部APM采集
  - 错误率可通过HTTP状态码分布统计
- 轮询与长连接
  - HTTP轮询模式下应限制轮询频率，避免CPU与带宽浪费
  - WebSocket心跳与超时可减少无效连接占用

[本节为通用性能指导，无需特定文件引用]

## 故障排查指南
- 常见问题
  - 会话不存在：HTTP处理器校验session-id，缺失或过期导致404
  - 连接ID冲突：私有模式下重复使用连接ID会触发400
  - WebSocket超时：长时间无活动将被自动断开
  - 文件上传失败：服务端重命名异常导致500
- 排查步骤
  - 启用更细粒度日志（info/log），复现问题并核对日志时间线
  - 使用Swagger查看接口规范，确认请求头与参数
  - 检查WebSocket消息类型与路由逻辑，确认角色与目标参与者
  - 对比前后两次RTCStats，定位带宽与帧率异常

**章节来源**
- [src/class/httphandler.ts:128-145](file://src/class/httphandler.ts#L128-L145)
- [src/class/httphandler.ts:747-763](file://src/class/httphandler.ts#L747-L763)
- [src/class/websockethandler.ts:404-430](file://src/class/websockethandler.ts#L404-L430)
- [src/server.ts:74-82](file://src/server.ts#L74-L82)

## 结论
本项目提供了清晰的日志体系与信令处理能力，结合Morgan访问日志与Swagger文档，能够满足日常运维与排障需求。建议在生产环境中：
- 明确日志级别与轮转策略，避免磁盘与IO压力
- 引入APM或Prometheus/Grafana进行指标采集与可视化
- 建立告警规则与通知通道，配合健康检查与自动恢复机制
- 使用分布式追踪定位跨服务链路瓶颈

[本节为总结性内容，无需特定文件引用]

## 附录

### 日志系统配置清单
- 日志级别
  - 可选：none/error/warn/log/info
  - 默认：info
- 输出格式
  - ISO时间戳 + 大写级别前缀
  - 区分 error/warn/info/log
- HTTP访问日志
  - 可选：combined/dev/short/tiny 或 none
  - 通过运行参数控制

**章节来源**
- [src/log.ts:1-51](file://src/log.ts#L1-L51)
- [src/server.ts:18-20](file://src/server.ts#L18-L20)
- [src/index.ts:28](file://src/index.ts#L28)

### 性能监控指标定义
- 连接数
  - WebSocket活跃连接数：基于连接集合统计
  - HTTP会话数与连接数：基于会话映射统计
- 内存使用
  - 服务端：关注Map/Set规模与消息队列长度
  - 客户端：媒体统计辅助判断编码与传输效率
- 请求响应时间与错误率
  - 通过中间件或外部APM采集
  - 错误率基于HTTP状态码分布

**章节来源**
- [src/class/websockethandler.ts:20-37](file://src/class/websockethandler.ts#L20-L37)
- [src/class/httphandler.ts:42-84](file://src/class/httphandler.ts#L42-L84)
- [client/public/js/stats.js:7-91](file://client/public/js/stats.js#L7-L91)

### 分布式追踪配置建议
- 链路跟踪
  - 在HTTP入口与WebSocket消息处理处打点
  - 关键节点：创建会话、创建连接、发送/接收offer/answer/candidate
- 瓶颈定位
  - 结合日志时间戳与追踪ID，定位慢查询与阻塞点
  - 媒体统计与网络指标联动分析

[本节为通用实践建议，无需特定文件引用]

### 告警规则与通知
- 阈值建议
  - 连接数：单节点并发连接数峰值阈值
  - 错误率：HTTP 5xx占比、WebSocket断连率
  - 响应时间：P95/P99延迟阈值
- 通知渠道
  - 邮件、IM、电话分级告警
- 故障恢复
  - 自动扩容、熔断降级、快速回滚

[本节为通用实践建议，无需特定文件引用]

### 监控工具集成要点
- Prometheus
  - 暴露指标端点，采集连接数、内存、请求速率与错误率
- Grafana
  - 仪表板展示趋势、告警与热力图
- ELK Stack
  - 收集HTTP与业务日志，建立检索与聚合分析

[本节为通用实践建议，无需特定文件引用]