【问题标题】:Convert a Log file to JSON file将日志文件转换为 JSON 文件
【发布时间】:2021-09-24 09:20:21
【问题描述】:

我想将日志文件转换为 JSON 格式。

Log文件内容如下:

2021-07-13T14:32:00.197904  DDD client=10.4.35.4
2021-07-13T14:32:00.271923  BBB from=<josh.josh@test.com>
2021-07-13T14:32:01.350434  CCC from=<rob.roder@test.com>
2021-07-13T14:32:01.417904  DDD message-id=<1-2-3-a-a@A1>
2021-07-13T14:32:01.586494  DDD from=<Will.Smith@test.com>
2021-07-13T14:32:02.643101  DDD to=<Will.Smith@test.com>
2021-07-13T14:32:02.712803  AAA client=10.1.35.2
2021-07-13T14:32:03.832661  BBB client=2021:8bd::98e7:2e04:f94s
2021-07-13T14:32:03.920297  DDD status=sent

但是出现的问题是我需要匹配每行的 ID 以导出到如下所示的 JSON:

  {
   "time": {
      "start": "2021-07-13T14:32:01.417904",
      "duration": "0:00:02.502393"
    },
    "sessionid": "DDD",
    "client": "10.4.35.4",
    "messageid": "<1-2-3-a-a@A1>",
    "address": {
        "from": "<Will.Smith@test.com>",
        "to": "<Will.Smith@test.com>"
    },
    "status": "sent"
  }
]

下一步是将此数据导入仅接受 JSON 格式的分析工具。我已经用 powershell 和 python 尝试过这个,但离预期的输出还很远。 一路走来的问题: 如何按会话链接每一行? 如何计算第一个和最后一个会话持续时间? 如何链接每个会话的第 3 列结果以及如何将它们转换为 json?

非常感谢任何帮助、链接、研究等。

【问题讨论】:

  • 请允许我给你一个标准的建议给新手:如果你accept 一个答案,你将帮助未来的读者,向他们展示解决了你的问题的方法。要接受答案,请单击答案左侧大数字下方的大 ✓ 符号(您将获得 2 点声望)。如果您至少有 15 个声望点,您还可以投票给其他有用的答案(也可以选择接受的答案)。如果您的问题尚未解决,请提供反馈,或者,如果您自己找到了解决方案,请self-answer

标签: json powershell logging text-parsing


【解决方案1】:

你可以做类似下面的事情:

Get-Content a.log | Foreach-Object {
    if ($_ -match '^(?<time>\S+)\s+(?<sessionid>\w+)\s+(?<key>[^=]+)=(?<data>.*)$') {
        [pscustomobject]@{
            time = $matches.time
            sessionid = $matches.sessionid
            key = $matches.key
            data = $matches.data
        } 
    }
} | Group sessionid | Foreach-Object {
    $jsonTemplate = [pscustomobject]@{
        time = [pscustomobject]@{ start = ''; duration = '' }
        sessionid = ''
        client = '' 
        messageid = ''
        address = [pscustomobject]@{from = ''; to = ''}
        status = ''
    }
    $start = ($_.Group | where key -eq 'message-id').time
    $end = ($_.Group | where key -eq 'status').time -as [datetime]
    $jsonTemplate.time.start = $start
    $jsonTemplate.time.duration = ($end - ($start -as [datetime])).ToString()
    $jsonTemplate.sessionid = $_.Name
    $jsonTemplate.client = ($_.Group | where key -eq 'client').data
    $jsonTemplate.messageid = ($_.Group | where key -eq 'message-id').data
    $jsonTemplate.address.from = ($_.Group | where key -eq 'from').data
    $jsonTemplate.address.to = ($_.Group | where key -eq 'to').data
    $jsonTemplate.status = ($_.Group | where key -eq 'status').data
    [regex]::Unescape(($jsonTemplate | convertTo-Json))
}

正在发生的一般步骤如下:

  1. 解析日志文件以分隔数据元素
  2. 按 sessionid 分组以轻松识别属于 session id 的所有事件条目
  3. 创建一个自定义对象,其中包含可轻松转换为所需 JSON 格式的架构。
  4. 正则表达式 unescape 是删除 &lt;&gt; 字符的 unicode 转义码。

-match 操作返回 $true 时,$matches 自动变量会更新。由于我们在正则表达式中使用命名捕获组,因此捕获组可以作为 $matches 哈希表中的键访问。


注意事项:

  • 假设 sessionid 每个 ID 只有一个会话。
  • 缺少的会话数据以 JSON 格式显示为 null。

读取文件时,替代解决方案可以使用ConvertFrom-String。对我个人来说,进行正则表达式匹配更简单。

【讨论】:

    【解决方案2】:

    基于switch 语句的解决方案,通过-File 参数实现快速的逐行处理:

    • 嵌套(有序)hashtable 用于跨行编译特定于会话的信息。

    • -split operator 用于将每一行拆分为字段,并将最后一个字段拆分为属性名称和值。

    注意:

    • 会话持续时间的计算假定给定会话 ID 的 第一行 行标记会话的开始,带有 status= 值的行标记会话结束。
    $sessions = [ordered] @{}
    switch -File file.log { # process file line by line
      default {
        $timestamp, $sessionId, $property = -split $_ # split the line into fields
        $name, $value = $property -split '=', 2       # split the property into name an value
        if ($session = $sessions.$sessionId) { # entry for session ID already exists
          $session.$name = $value
          # end of session? calculate the duration
          if ($name -eq 'status') { $session.time.duration = ([datetime] $timestamp - [datetime] $session.time.start).ToString() }
        } 
        else { # create new entry for this session ID
          $sessions.$sessionId = [ordered] @{
            $name = $value
            time = [ordered] @{
              start = $timestamp
              duration = $null
            }
          }
        }
      }  
    }
    
    # Convert the hashtable to JSON
    $sessions | ConvertTo-Json
    

    【讨论】:

      猜你喜欢
      • 2023-04-10
      • 1970-01-01
      • 2019-12-10
      • 2017-03-02
      • 2020-12-17
      • 2021-07-24
      • 2011-02-19
      • 1970-01-01
      • 2018-10-23
      相关资源
      最近更新 更多