77 lines
2.1 KiB
Go
77 lines
2.1 KiB
Go
package transport
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
)
|
|
|
|
// KCPPacketDebugRecord 是 KCP 底层 UDP packet kernel timestamp 的一条 JSONL 调试记录。
|
|
type KCPPacketDebugRecord struct {
|
|
Event string `json:"event"`
|
|
NodeRole string `json:"node_role,omitempty"`
|
|
NodeID string `json:"node_id,omitempty"`
|
|
LocalAddr string `json:"local_addr,omitempty"`
|
|
RemoteAddr string `json:"remote_addr,omitempty"`
|
|
PacketBytes int `json:"packet_bytes"`
|
|
UDPTXID *uint32 `json:"udp_tx_id,omitempty"`
|
|
KCPConv *uint32 `json:"kcp_conv,omitempty"`
|
|
TSUnixNano int64 `json:"ts_unix_nano"`
|
|
}
|
|
|
|
// KCPPacketDebugLogger 接收 KCP packet 级调试记录。
|
|
type KCPPacketDebugLogger interface {
|
|
LogKCPPacketDebugRecord(record KCPPacketDebugRecord) error
|
|
}
|
|
|
|
// JSONLKCPPacketDebugLogger 以 JSONL 形式追加写 KCP packet 调试日志。
|
|
type JSONLKCPPacketDebugLogger struct {
|
|
mu sync.Mutex
|
|
closeOnce sync.Once
|
|
closeErr error
|
|
file *os.File
|
|
}
|
|
|
|
// NewJSONLKCPPacketDebugLogger 创建一个线程安全的 KCP packet JSONL 日志器。
|
|
func NewJSONLKCPPacketDebugLogger(path string) (*JSONLKCPPacketDebugLogger, error) {
|
|
dir := filepath.Dir(path)
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
return nil, fmt.Errorf("transport: create kcp packet debug log dir %s: %w", dir, err)
|
|
}
|
|
|
|
file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("transport: open kcp packet debug log %s: %w", path, err)
|
|
}
|
|
|
|
return &JSONLKCPPacketDebugLogger{file: file}, nil
|
|
}
|
|
|
|
// LogKCPPacketDebugRecord 以单行 JSON 的形式追加一条 KCP packet 调试记录。
|
|
func (l *JSONLKCPPacketDebugLogger) LogKCPPacketDebugRecord(record KCPPacketDebugRecord) error {
|
|
line, err := json.Marshal(record)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
|
|
if _, err := l.file.Write(append(line, '\n')); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Close 关闭底层文件;重复调用是安全的。
|
|
func (l *JSONLKCPPacketDebugLogger) Close() error {
|
|
l.closeOnce.Do(func() {
|
|
l.closeErr = l.file.Close()
|
|
})
|
|
|
|
return l.closeErr
|
|
}
|