Vpp-Agent 支持 log 写文件

需求分析

vpp-agent 现有的日志都是通过标准输出展示的,且输出的方式有至少三种: std 、 logrusLog 第三方包、 cn-infra logger 工具。

现需要将 vpp-agent 日志保存到文件中,以便在对接 mep 平台时可以定位跟踪代码流程。考虑到现有 vpp-agent 的日志输出方式不统一,如果全部修改影响较大,故先修改 upfplugin 的日志输出,保证 upf 和 mep 的对接,其他内容后续使用到再做修改。

详细设计

1、修改配置加载部分,使之能加载日志配置:

日志配置:路径、文件名、日志级别(使用原有日志级别配置即可)

// 在 upfplugin.go 文件中修改
// 增加读取配置项 LogFile 和 LogLevel
type Config struct {
	Publishers []string `json:"publishers"`
	InstanceID string   `json:"instanceid"`
	GrpcServer string   `json:"grpcserver"`
	LogFile    string   `json:"logfile"`
	LogLevel   uint32   `json:"loglevel"`
}

// 在读取函数中增加处理
func (p *UpfPlugin) loadConfig() (*Config, error) {
    // ……
	fileName := config.LogFile
	if fileName == "" {
		fileName = "/var/log/vpp-agent/vpp-agent-upf-default.log"
	}
	upfLogFile, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_SYNC,0777)
	if err != nil {
		p.Log.Error("Error open logfile [%v] : %v", fileName, err)
		return nil, err
	}
	p.Log.SetOutput(upfLogFile)

	logLevel := config.LogLevel
	switch logLevel {
	case 0:
		p.Log.SetLevel(logging.PanicLevel)
	case 1:
		p.Log.SetLevel(logging.FatalLevel)
	case 2:
		p.Log.SetLevel(logging.ErrorLevel)
	case 3:
		p.Log.SetLevel(logging.WarnLevel)
	case 4:
		p.Log.SetLevel(logging.InfoLevel)
	case 5:
		p.Log.SetLevel(logging.DebugLevel)
	}
    // ……
    return config, err
}

2、修改 upfplugin 中各个 descriptor 初始化时的日志配置:

原有 descriptor 初始化时加载日志使用创建 logger 对象的方式,现修改为直接使用 upfplugin 的 logger 对象:

// 在各个 descriptor 的 NewArpDescriptor 方法中
xxx := &XXXDescriptor{
	// ……
	// log:        log.NewLogger("arp-descriptor"),
	log:        log,  // 无需另外创建 logger ,直接使用 upfplugin 的 logger 即可
}
 

此次修改涉及的 descriptor 如下:

arp_entry.go
gtpu_endpoint.go
ha_status.go
mp2_acl_rule.go
mp2_bandwidth_rule.go
mp2_dns_redirect_rule.go
mp2_dns_rule.go
mp2_traffic_rule.go
nwi.go
pfcp_association.go
pfcp_bar.go
pfcp_endpoint.go
pfcp_far.go
pfcp_pdr.go
pfcp_pfd_management.go
pfcp_qer.go
pfcp_session.go
pfcp_urr.go
predefined_far.go
predefined_qer.go
predefined_rule.go
predefined_urr.go
utils.go

测试

1、启动 vpp-agent 前写日志配置:

vpp-agent_log_test_1.png

loglevel : 日志级别( 0 - Panic ; 1 - Fatal ; 2 - Error ; 3 - Warn ; 4 - Info ; 5 - Debug )

logfile : 带路径的日志文件名,如果不写,程序中默认使用 /var/log/vpp-agent/vpp-agent-upf-default.log 作为日志。

2、日志展示:

# 日志包括 redis 等依赖插件的注册信息
time="2021-10-25 06:32:59.87406" level=info msg="Added status publisher \"redis\" from config" loc="upfplugin/upfplugin.go(485)" logger=vpp-upfplugin
# 监控 KV 数据库的事件
time="2021-10-25 06:32:59.88250" level=debug msg="start watching interface events" loc="vpp2005/watch_vppcalls.go(55)" logger=vpp-upfplugin
# 在库的 prefix 清单
time="2021-10-25 06:32:59.88677" level=info msg="prefix config/vpp/upf/v2/ha/ type ligato.vpp.upf.HAStatus\n" loc="descriptor/ha_status.go(53)" logger=vpp-upfplugin
time="2021-10-25 06:32:59.99782" level=info msg="subscribe to 1 context prefixes: [config/vpp/upf/v2/ha/]" loc="upfplugin/upfplugin.go(498)" logger=vpp-upfplugin
# 记录各模块的处理流程
time="2021-10-25 06:33:00.20184" level=debug msg="Update Mp2 bandwidth rule by mepId:\"123\" appName:\"1030\" bwAllocationRuleId:\"094e2e23\" sessionFilter:{sourceIp:\"172.20.231.0\" sourcePort:\"9999\" destinationIp:\"172.20.231.1\" destinationPort:\"9999\" protocol:\"17\"} fixedBWPriority:1 fixedAllocation:1000 allocationDirection:\"00\" action:\"add\"\n" loc="vpp2009/upf_vppcalls.go(945)" logger=vpp-upfplugin
time="2021-10-25 06:33:00.20452" level=debug msg="send request to upf &{AppName:1030 AllocationRuleID:094e2e23 SessionFilter:{SourceIP:172.20.231.0 Supi: Gpsi: DestinationIP:172.20.231.1 SourcePort:9999 DestinationPort:9999 Protocol:17} FixedPriority:1 FixedAllocati:1000 AllocationDirection:00 Action:add}\n" loc="vpp2009/upf_vppcalls.go(967)" logger=vpp-upfplugin
time="2021-10-25 06:33:00.20304" level=info msg="=> received RESYNC event (1 prefixes)" loc="upfplugin/upfplugin.go(551)" logger=vpp-upfplugin
time="2021-10-25 06:33:00.20809" level=info msg="Resync with 0 items" loc="upfplugin/upfplugin.go(583)" logger=vpp-upfplugin
time="2021-10-25 06:33:00.20613" level=error msg="VppUpdateMP2BandWidthRule error VPPApiError: Invalid sw_if_index #2 (-10)" loc="descriptor/mp2_bandwidth_rule.go(93)" logger=vpp-upfplugin
time="2021-10-25 06:33:00.20943" level=debug msg="Pushing data with 0 KV pairs (source: filedb)" loc="upfplugin/dispatcher.go(73)" logger=vpp-upfplugin
time="2021-10-25 06:33:00.21201" level=info msg="Transaction #2 successful! (took 0s)" loc="upfplugin/dispatcher.go(128)" logger=vpp-upfplugin