resurfaceio goreplay output-resurface 处理简单说明

resurfaceio goreplay output-resurface 的处理实际上就是开发了一个新的output 插件,对于数据的写入是使用了
resurfaceio 的golang logger sdk

实现简单说明

output_resurface.go,核心就是一个标准的goreplay plugin,通过go channel 实现消息处理,包装为一个自己的http message
之后通过 logger sdk 写入到resurfaceio api 服务中

  • 消息处理
func (o *ResurfaceOutput) buildMessages() {
    // Keep track of both requests and responses for matching
    messages := make(map[string]*HTTPMessage, o.config.bufferSize)
    // Manually check and remove orphaned requests/responses every 10 s
    straysTicker := time.NewTicker(time.Second * 10)
    // (Debug) Count messages received/sent
    messageCounter := [3]int{0, 0, 0}
    for {
        select {
        case msg := <-o.messages:
            messageCounter[0]++
            metaSlice := payloadMeta(msg.Meta)
            // UUID shared by a given request and its corresponding response
            messageID := byteutils.SliceToString(metaSlice[1])
 
            message, messageFound := messages[messageID]
            if !messageFound {
                // Message timestamp
                messageTimestamp := byteutils.SliceToString(metaSlice[2])
 
                message = &HTTPMessage{}
                messages[messageID] = message
 
                messageTime, err := strconv.ParseInt(messageTimestamp, 10, 64)
                if err == nil {
                    message.initTime = time.Unix(0, messageTime)
                } else {
                    message.initTime = time.Now()
                    Debug(2, logPrefix, "Error parsing message timestamp", err.Error())
                }
            }
 
            reqFound := message.request != nil
            if !reqFound && isRequestPayload(msg.Meta) {
                message.request = msg
                reqFound = true
            }
 
            respFound := message.response != nil
            if !respFound && !isRequestPayload(msg.Meta) {
                message.response = msg
                respFound = true
            }
 
            if reqFound && respFound {
                o.httpMessages <- message
                messageCounter[1]++
                delete(messages, messageID)
            }
 
        case <-straysTicker.C:
            if n := len(messages); n > 0 {
                Debug(3, logPrefix, "Number of messages in queue:", n)
                for id, message := range messages {
                    Debug(4, logPrefix, "Checking message:", id)
                    hasRequest := message.request != nil
                    hasResponse := message.response != nil
                    if ((hasRequest && !hasResponse) || (!hasRequest && hasResponse)) &&
                        time.Since(message.initTime) >= time.Minute*2 {
 
                        Debug(3, logPrefix, "STRAY MESSAGE:", id)
                        if Settings.Verbose > 3 {
                            if hasRequest {
                                Debug(4, logPrefix, "REQUEST:", byteutils.SliceToString(message.request.Meta))
                                Debug(5, logPrefix, "REQUEST:\n", byteutils.SliceToString(message.request.Data))
                            }
                            if hasResponse {
                                Debug(4, logPrefix, "RESPONSE:", byteutils.SliceToString(message.response.Meta))
                                Debug(5, logPrefix, "RESPONSE:\n", byteutils.SliceToString(message.response.Data))
                            }
                        }
 
                        delete(messages, id)
                        Debug(3, logPrefix, "MESSAGE", id, "DELETED")
                        messageCounter[2]++
                    }
                }
            }
            if messageCounter[0]+messageCounter[1]+messageCounter[2] != 0 {
                Debug(1, logPrefix, "messages received:", messageCounter[0],
                    ", full messages sent:", messageCounter[1], ", orphans deleted:", messageCounter[2])
                messageCounter = [3]int{0, 0, 0}
            }
        }
    }
}
  • 数据写入处理
func (o *ResurfaceOutput) sendMessages() {
    for message := range o.httpMessages {
        req, reqErr := http.ReadRequest(bufio.NewReader(bytes.NewReader(message.request.Data)))
        if reqErr != nil {
            continue
        }
 
        resp, respErr := http.ReadResponse(bufio.NewReader(bytes.NewReader(message.response.Data)), req)
        if respErr != nil {
            continue
        }
 
        reqMeta := payloadMeta(message.request.Meta)
        respMeta := payloadMeta(message.response.Meta)
 
        //Debug(4, "[OUTPUT][RESURFACE]", "Processing Message:", id)
        if Settings.Verbose > 4 {
            Debug(5, logPrefix, "Processing Request:", byteutils.SliceToString(reqMeta[1]))
            Debug(6, logPrefix, byteutils.SliceToString(message.request.Data))
            Debug(5, logPrefix, "Processing Response:", byteutils.SliceToString(respMeta[1]))
            Debug(6, logPrefix, byteutils.SliceToString(message.response.Data))
        }
 
        reqTimestamp, _ := strconv.ParseInt(byteutils.SliceToString(reqMeta[2]), 10, 64)
        respTimestamp, _ := strconv.ParseInt(byteutils.SliceToString(respMeta[2]), 10, 64)
 
        interval := (respTimestamp - reqTimestamp) / 1000000
        if interval < 0 {
            interval = 0
        }
 
        resurfaceLogger.SendHttpMessage(o.rLogger, resp, req, respTimestamp/1000000, interval, nil)
    }
}

说明

resurfaceio goreplay 的实现并不难,实际上我们也可以基于此实现一个graylog gelf 协议的

参考资料

https://resurface.io/docs
https://github.com/resurfaceio/goreplay
https://github.com/resurfaceio/logger-go

posted on   荣锋亮  阅读(6)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2022-03-08 krakend 2.0.0 发布了
2022-03-08 dremio ConnectionConf 接口说明
2022-03-08 dremio SourceMetadataManager 服务简单说明
2020-03-08 pgspider Citu 副本以及节点移除简单学习
2020-03-08 Citus 官方docker demo 中membership-manager原理简单说明
2020-03-08 pgspider Citus docker 镜像使用
2019-03-08 nginx unit 1.8 支持基于java servlet 的开发模型

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示