微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将日志文件转换为 JSON 文件

如何解决将日志文件转换为 JSON 文件

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

日志文件内容如下:

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?

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

解决方法

您可以执行以下类似操作:

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 分组以轻松识别属于会话 id 的所有事件条目
  3. 创建一个自定义对象,其中包含可轻松转换为所需 JSON 格式的架构。
  4. 正则表达式 unescape 是删除 <> 字符的 unicode 转义码。

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


注意事项:

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

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

,

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

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

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

注意:

  • 会话持续时间的计算假定给定会话 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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。