github.com/benz9527/xboot@v0.0.0-20240504061247-c23f15593274/helpers/fluentbit/crio.lua (about)

     1  _G.JSON = {
     2      escape = "\\",
     3      comma = ",",
     4      colon = ":",
     5      null = "null",
     6      quotes = '"',
     7      left_brace = '{',
     8      right_brace = '}',
     9      left_square_bracket = '[',
    10      right_square_bracket = ']'
    11  }
    12  JSON._trim = function(target) return target and string.gsub(target, "^%s*(.-)%s*$", "%1") end
    13  -- parse json key or value from stringify json
    14  -- @return string(metadata),string(rest string)
    15  JSON._parse = function(str)
    16      local chStack, index, lastCh = {}, 1
    17      while index <= #str do
    18          local ch = string.sub(str, index, index)
    19          if JSON.quotes == ch then
    20              if ch == lastCh then
    21                  table.remove(chStack, #chStack)
    22                  lastCh = #chStack > 0 and chStack[#chStack] or nil
    23              else
    24                  lastCh = ch
    25                  table.insert(chStack, lastCh)
    26              end
    27          elseif JSON.escape == ch then
    28              str = string.sub(str, 1, index - 1) .. string.sub(str, index + 1)
    29          end
    30          if JSON.quotes ~= lastCh then
    31              if JSON.left_brace == ch then
    32                  table.insert(chStack, JSON.right_brace)
    33                  lastCh = ch
    34              elseif JSON.left_square_bracket == ch then
    35                  table.insert(chStack, JSON.right_square_bracket)
    36                  lastCh = ch
    37              elseif JSON.right_brace == ch or JSON.right_square_bracket == ch then
    38                  assert(lastCh == ch, str .. " : " .. index .. " unexpected " .. ch .. "<->" .. lastCh)
    39                  table.remove(chStack, #chStack)
    40                  lastCh = #chStack > 0 and chStack[#chStack] or nil
    41              elseif JSON.comma == ch or JSON.colon == ch then
    42                  if not lastCh then return string.sub(str, 1, index - 1), string.sub(str, index + 1) end
    43              end
    44          end
    45          index = index + 1
    46      end
    47      return string.sub(str, 1, index - 1), string.sub(str, index + 1)
    48  end
    49  -- stringify json to lua table
    50  JSON.toJSON = function(str)
    51      str = JSON._trim(str)
    52      -- handle string
    53      -- return plain string, not stringify json
    54      if JSON.quotes == string.sub(str, 1, 1) and JSON.quotes == string.sub(str, -1, -1) then
    55          return string.sub(
    56              JSON._parse(str), 2, -2)
    57      end
    58      if 4 == #str then
    59          -- handle boolean and nil
    60          local lower = string.lower(str)
    61          if "true" == lower then
    62              return true
    63          elseif "false" == lower then
    64              return false
    65          elseif JSON.null == lower then
    66              return nil
    67          end
    68      end
    69      -- handle number
    70      local n = tonumber(str)
    71      if n then return n end
    72      -- handle array
    73      if JSON.left_square_bracket == string.sub(str, 1, 1) and JSON.right_square_bracket == string.sub(str, -1, -1) then
    74          local rest = string.gsub(str, "[\r\n]+", "")
    75          rest = string.sub(rest, 2, -2)
    76          local arr, index, val = {}, 1
    77          while #rest > 0 do
    78              val, rest = JSON._parse(rest)
    79              if val then
    80                  val = JSON.toJSON(val)
    81                  arr[index] = val
    82                  index = index + 1
    83              end
    84          end
    85          return arr
    86      end
    87      -- handle table
    88      if JSON.left_brace == string.sub(str, 1, 1) and JSON.right_brace == string.sub(str, -1, -1) then
    89          local rest = string.gsub(str, "[\r\n]+", "")
    90          rest = string.sub(rest, 2, -2)
    91          local key, val
    92          local tbl = {}
    93          while #rest > 0 do
    94              key, rest = JSON._parse(rest)
    95              val, rest = JSON._parse(rest)
    96              if key and #key > 0 and val then
    97                  key = JSON.toJSON(key)
    98                  val = JSON.toJSON(val)
    99                  if key and val then tbl[key] = val end
   100              end
   101          end
   102          return tbl
   103      end
   104      -- parse error
   105      return nil
   106  end
   107  -- https://docs.fluentbit.io/manual/pipeline/filters/lua
   108  -- Maybe you have to update the following function to match your real log format.
   109  -- Log example: 
   110  -- 2023-03-31T15:35:48.917244985+00:00 stdout F {"level":"INFO","timestamp":"2023-03-31T15:35:48.917Z","caller":"logger/console.go:138","message":"ignored proxy module [auth]","service":"auth","request-trace-id":"__internal__","pod-info":{"ip":"10.128.2.66","uid":"368a8103-2c54-4e3b-8b37-627aa06544a9","name":"omc-auth-ss-0","namespace":"xxx","node":"worker3.dev","node-ip":"172.29.13.164","software":{"build-date":"2023-03-28 07:11:01","app-version":"1.0.0-dev","dev-kit-version":"go1.20.2","git-commit":"8bd57509da035bc4e19fab5e2fe9a2d960373de4","mode":"dev/linux/amd64"}}}
   111  -- fluentbit log match and extract regexpr:
   112  -- ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>[^ ]*) (?<log>.*)$
   113  function nest_to_json(tag, timestamp, record)
   114      local str_json = record["log"]
   115      local json = JSON.toJSON(str_json)
   116      if not json then
   117          return 0, timestamp, record
   118      end
   119      local tbl = {}
   120      for k, v in pairs(json) do
   121          if k and "pod-info" == k and "table" == type(v) then
   122              for k1, v1 in pairs(v) do
   123                  tbl[k1] = v1
   124              end
   125          elseif k and "timestamp" == k or "@timestamp" == k then
   126              tbl["app@ts"] = v
   127          else
   128              tbl[k] = v
   129          end
   130      end
   131      -- crio log flag
   132      tbl["stream"] = record["stream"]
   133      return 2, timestamp, tbl
   134  end