在 Vue 客户端中将日志文件数据转换为 Json 对象

Posted

技术标签:

【中文标题】在 Vue 客户端中将日志文件数据转换为 Json 对象【英文标题】:Convert log File Data to Json Object in Vue client 【发布时间】:2021-12-16 16:32:36 【问题描述】:

我有一个日志文件如下:

"L":"DEBUG","T":"2021-11-01T17:37:54.167+0530","M":"Route.go:74[IN : GetLatestLogs]"
"L":"DEBUG","T":"2021-11-01T17:37:54.167+0530","M":"Service.go:40[IN : GetRecentServerErrorLogService]"
"L":"DEBUG","T":"2021-11-01T17:37:54.167+0530","M":"DAO.go:117[IN : GetRecentServerErrorLogDAO]"
"L":"DEBUG","T":"2021-11-01T17:37:54.168+0530","M":"DAO.go:148[OUT : GetRecentServerErrorLogDAO]"
"L":"DEBUG","T":"2021-11-01T17:37:54.168+0530","M":"Service.go:47[OUT : GetRecentServerErrorLogService]"
"L":"DEBUG","T":"2021-11-01T17:37:54.168+0530","M":"Route.go:79[OUT : GetLatestLogs]"
"L":"DEBUG","T":"2021-11-01T17:40:55.331+0530","M":"Route.go:74[IN : GetLatestLogs]"

我在 Golang 回显服务器中读取这个文件如下:

file, err := os.Open(logFilePath)

stat, _ := os.Stat(logFilePath)
buf := make([]byte, stat.Size())
_, err = file.Read(buf)
serverLog := string(buf)

并返回这个生成的字符串

return c.JSON(http.StatusOK, serverLog)

这是我得到的结果

"\"L\":\"DEBUG\",\"T\":\"2021-11-01T17:37:54.167+0530\",\"M\":\"Route.go:74[IN : GetLatestLogs]\"\n\"L\":\"DEBUG\",\"T\":\"2021-11-01T17:37:54.167+0530\",\"M\":\"Service.go:40[IN : GetRecentServerErrorLogService]\"\n\"L\":\"DEBUG\",\"T\":\"2021-11-01T17:37:54.167+0530\",\"M\":\"DAO.go:117[IN : GetRecentServerErrorLogDAO]\"\n\"L\":\"DEBUG\",\"T\":\"2021-11-01T17:37:54.168+0530\",\"M\":\"DAO.go:148[OUT : GetRecentServerErrorLogDAO]\"\n\"L\":\"DEBUG\",\"T\":\"2021-11-01T17:37:54.168+0530\",\"M\":\"Service.go:47[OUT : GetRecentServerErrorLogService]\"\n\"L\":\"DEBUG\",\"T\":\"2021-11-01T17:37:54.168+0530\",\"M\":\"Route.go:79[OUT : GetLatestLogs]\"\n\"L\":\"DEBUG\",\"T\":\"2021-11-01T17:40:55.331+0530\",\"M\":\"Route.go:74[IN : GetLatestLogs]\"\"L\":\"DEBUG\",\"T\":\"2021-11-02T09:48:49.982+0530\",\"M\":\"controlPanelRoute.go:74[IN : GetLatestLogs]\"\n\"L\":\"DEBUG\",\"T\":\"2021-11-02T09:48:49.982+0530\",\"M\":\"controlPanelService.go:40[IN : GetRecentServerErrorLogService]\"\n\"L\":\"DEBUG\",\"T\":\"2021-11-02T09:48:49.982+0530\",\"M\":\"controlPanelDAO.go:117[IN : GetRecentServerErrorLogDAO]\"\n"

我想将此收到的响应转换为 JSON 对象。

这是我想要的输出:

[
    
        "L": "DEBUG",
        "T": "2021-11-01T17:37:54.167+0530",
        "M": "Route.go:74[IN : GetLatestLogs]"
    ,
    
        "L": "DEBUG",
        "T": "2021-11-01T17:37:54.167+0530",
        "M": "Service.go:40[IN : GetRecentServerErrorLogService]"
    ,
    
        "L": "DEBUG",
        "T": "2021-11-01T17:37:54.167+0530",
        "M": "DAO.go:117[IN : GetRecentServerErrorLogDAO]"
    ,
    
        "L": "DEBUG",
        "T": "2021-11-01T17:37:54.168+0530",
        "M": "DAO.go:148[OUT : GetRecentServerErrorLogDAO]"
    ,
    
        "L": "DEBUG",
        "T": "2021-11-01T17:37:54.168+0530",
        "M": "Service.go:47[OUT : GetRecentServerErrorLogService]"
    ,
    
        "L": "DEBUG",
        "T": "2021-11-01T17:37:54.168+0530",
        "M": "Route.go:79[OUT : GetLatestLogs]"
    ,
    
        "L": "DEBUG",
        "T": "2021-11-01T17:40:55.331+0530",
        "M": "Route.go:74[IN : GetLatestLogs]"
    
]

【问题讨论】:

【参考方案1】:

这看起来像是一个接一个有效的 Json 语句。您可以打开该文件,使用json.NewDecoder(filehandle) 创建一个解码器,然后读取一个 Json 语句(如果它一个接一个)。这是输入硬编码的示例:

package main

import (
    "fmt"
    "bytes"
    "io"
    "encoding/json"
)

var input =[]byte( `"L":"DEBUG","T":"2021-11-01T17:37:54.167+0530","M":"Route.go:74[IN : GetLatestLogs]"
"L":"DEBUG","T":"2021-11-01T17:37:54.167+0530","M":"Service.go:40[IN : GetRecentServerErrorLogService]"
"L":"DEBUG","T":"2021-11-01T17:37:54.167+0530","M":"DAO.go:117[IN : GetRecentServerErrorLogDAO]"
"L":"DEBUG","T":"2021-11-01T17:37:54.168+0530","M":"DAO.go:148[OUT : GetRecentServerErrorLogDAO]"
"L":"DEBUG","T":"2021-11-01T17:37:54.168+0530","M":"Service.go:47[OUT : GetRecentServerErrorLogService]"
"L":"DEBUG","T":"2021-11-01T17:37:54.168+0530","M":"Route.go:79[OUT : GetLatestLogs]"
"L":"DEBUG","T":"2021-11-01T17:40:55.331+0530","M":"Route.go:74[IN : GetLatestLogs]"`)

func main() 
    r := json.NewDecoder(bytes.NewBuffer(input))
    var data interface
    for i := 0;;i++
        if err := r.Decode(&data); err != nil 
            if err == io.EOF 
                break
            
            panic(err)
         else 
            fmt.Printf("%d: %+v\n", i, data)
        
    

输出应该是:

0: map[L:DEBUG M:Route.go:74[IN : GetLatestLogs] T:2021-11-01T17:37:54.167+0530]
1: map[L:DEBUG M:Service.go:40[IN : GetRecentServerErrorLogService] T:2021-11-01T17:37:54.167+0530]
2: map[L:DEBUG M:DAO.go:117[IN : GetRecentServerErrorLogDAO] T:2021-11-01T17:37:54.167+0530]
3: map[L:DEBUG M:DAO.go:148[OUT : GetRecentServerErrorLogDAO] T:2021-11-01T17:37:54.168+0530]
4: map[L:DEBUG M:Service.go:47[OUT : GetRecentServerErrorLogService] T:2021-11-01T17:37:54.168+0530]
5: map[L:DEBUG M:Route.go:79[OUT : GetLatestLogs] T:2021-11-01T17:37:54.168+0530]
6: map[L:DEBUG M:Route.go:74[IN : GetLatestLogs] T:2021-11-01T17:40:55.331+0530]

如您所见,Decode() 停在 Json 表达式的末尾,因此您可以一遍又一遍地继续阅读。

【讨论】:

【参考方案2】:
file, err := os.Open("/log/file/path")
if err != nil 
    panic(err)

info, err := file.Stat()
if err != nil 
    panic(err)


logs := make(json.RawMessage, 1, info.Size()+1) // len=1 for '['
dec := json.NewDecoder(file)
for dec.More() 
    var log json.RawMessage
    if err := dec.Decode(&log); err != nil 
        panic(err)
    

    logs = append(logs, log...)
    logs = append(logs, ',')

if n := len(logs); n > 1 
    logs[0], logs[n-1] = '[', ']'
    c.JSON(http.StatusOK, logs)

【讨论】:

【参考方案3】:

从您的代码看来,您依赖 Gin 为您进行转换:

return c.JSON(http.StatusOK, serverLog)

您实际上可以自己处理它,但它可能需要逐行解组,因为日志文本文件不是有效的 JSON 数组。然后我将有效结构编组回 JSON。在下面的示例中,我使用 bufio 逐行读取文本文件,并解组为 Log 结构:

package main

import (
    "os"
    "fmt"
    "encoding/json"
    "bufio"
)

type Log struct 
    L   string
    T   string
    M   string


func main() 
    f, err := os.Open("log.txt")
    defer f.Close()

    var logs []Log
    var log Log

    input := bufio.NewScanner(f)

    for input.Scan() 
        textByte := []byte(input.Text())
        err = json.Unmarshal(textByte, &log)
        if err != nil 
            fmt.Printf("Problems with unmarshalling: %v\n", err)
            os.Exit(1)
        
        logs = append(logs, log)
    

    data, err := json.MarshalIndent(logs, "", "    ")
    if err != nil 
        fmt.Printf("Error in marshalling: %v\n", err)
        os.Exit(1)
    

    fmt.Printf("%s\n", data)

或者你可以从函数中返回字符串:

return fmt.Sprintf("%s\n", data)

这是输出:

[
    
        "L": "DEBUG",
        "T": "2021-11-01T17:37:54.167+0530",
        "M": "Route.go:74[IN : GetLatestLogs]"
    ,
    
        "L": "DEBUG",
        "T": "2021-11-01T17:37:54.167+0530",
        "M": "Service.go:40[IN : GetRecentServerErrorLogService]"
    ,
    
        "L": "DEBUG",
        "T": "2021-11-01T17:37:54.167+0530",
        "M": "DAO.go:117[IN : GetRecentServerErrorLogDAO]"
    ,
    
        "L": "DEBUG",
        "T": "2021-11-01T17:37:54.168+0530",
        "M": "DAO.go:148[OUT : GetRecentServerErrorLogDAO]"
    ,
    
        "L": "DEBUG",
        "T": "2021-11-01T17:37:54.168+0530",
        "M": "Service.go:47[OUT : GetRecentServerErrorLogService]"
    ,
    
        "L": "DEBUG",
        "T": "2021-11-01T17:37:54.168+0530",
        "M": "Route.go:79[OUT : GetLatestLogs]"
    ,
    
        "L": "DEBUG",
        "T": "2021-11-01T17:40:55.331+0530",
        "M": "Route.go:74[IN : GetLatestLogs]"
    
]

【讨论】:

以上是关于在 Vue 客户端中将日志文件数据转换为 Json 对象的主要内容,如果未能解决你的问题,请参考以下文章

在 Scala 中将 JSON 转换为 CSV?

在 Python 中将 JSON 转换为 HTML 表

如何在 bash 中将 json 响应转换为 yaml

在javascript中将树从db格式转换为json格式

在 React 中将 Object 转换为 JSON 并下载为 .json 文件

如何在喷雾中将所有拒绝转换为自定义 json?