Jq trim with regex or position of char

huangapple go评论73阅读模式
英文:

Jq trim with regex or position of char

问题

The CloudWatch log format for Aurora PostgreSQL delayed queries can be transformed into the desired HTML table format using the jq command. Here's a jq command that will achieve this:

jq -r '
  .events[] | select(.message | contains("duration:")) | .message | capture("^(?<timestamp>[^:]+):(?<clientIP>[^:]+)\\((?<port>[^)]+)\\):(?<userDB>[^@]+)@postgres:\\[(?<pid>[^]]+)\\]:LOG:  duration: (?<duration>[^ ]+) ms  statement: (?<query>.*)$") | "<tr><td>\(.timestamp)</td><td>\(.clientIP)</td><td>\(.userDB)</td><td>\(.duration)</td><td>\(.query)</td></tr>"' your_input_file.json

Replace your_input_file.json with the actual filename containing your JSON data.

This jq command will parse the JSON data, extract the relevant fields from the "message" field, and format them into an HTML table row (<tr>) with table data (<td>) for each field. It will produce the clean HTML table format you desire.

英文:

The CloudWatch log format for Aurora Postgresql delayed queries is as follows.

{
    &quot;nextForwardToken&quot;: &quot;f/37657393414703861243420284798371757973629840396172525568/s&quot;, 
    &quot;events&quot;: [
        {
            &quot;ingestionTime&quot;: 1688615727267, 
            &quot;timestamp&quot;: 1688615724000, 
            &quot;message&quot;: &quot;2023-07-06 03:55:24 UTC:11.11.11.11(51400):testUser@postgres:[9802]:LOG:  duration: 2004.016 ms  statement: select pg_sleep(2);&quot;
        }, 
        {
            &quot;ingestionTime&quot;: 1688615925270, 
            &quot;timestamp&quot;: 1688615922000, 
            &quot;message&quot;: &quot;2023-07-06 03:58:42 UTC:111.22.331.41(1230):testService@postgres:[8602]:LOG:  duration: 2009.526 ms  statement: select pg_sleep(2);&quot;
        }
    ], 
    &quot;nextBackwardToken&quot;: &quot;b/37657388999156311934356902534929058635511305773902397440/s&quot;
}

I want to create html format using jq command.
I want to parse message field and The desired format like this:

Time(UTC) clientIP user@db Query_time(ms) Query
2023-07-06 03:55:24 11.11.11.11 testUser@postgres 2004.016 select pg_sleep(2)
2023-07-06 03:58:42 111.22.331.41 testService@postgres 2009.526 select pg_sleep(2)

To create the table, I tried various methods.

<1><br>
I wanted to apply the pattern to startswith and trim, but I couldn't find the material and it didn't apply.

/usr/local/bin/jq -r &#39;
def to_row: &quot;&lt;tr&gt;&quot;,.[],&quot;&lt;/tr&gt;&quot;;
def to_cell: &quot;&lt;td&gt;&quot;,.,&quot;&lt;/td&gt;&quot;;
(
  .events[] | select(.message | contains(&quot;duration:&quot;)) | .message/&quot;\n&quot; | map(
    (select(startswith(&quot;\(.[0:4])-\(.[4:6])-\(.[6:8]) \(.[8:10]):\(.[10:12]):\(.[12:14])&quot;)))
  | map(@html | to_cell)
  | to_row
)
&#39;

<2><br>
This method seems to be able to split the fields, but not in the desired direction.

.events[] | .message | split(&quot;:&quot;)

&lt;tr&gt;
&lt;td&gt;
2023-07-06 03
&lt;/td&gt;
&lt;td&gt;
55
&lt;/td&gt;
&lt;td&gt;
24 UTC
&lt;/td&gt;
&lt;td&gt;
11.11.11.11(51400)
&lt;/td&gt;
&lt;td&gt;
testUser@postgres
&lt;/td&gt;
&lt;td&gt;
[9802]
&lt;/td&gt;
&lt;td&gt;
LOG
&lt;/td&gt;
&lt;td&gt;
  duration
&lt;/td&gt;
&lt;td&gt;
 2004.016 ms  statement
&lt;/td&gt;
&lt;td&gt;
 select pg_sleep(2);
&lt;/td&gt;
&lt;/tr&gt;

Is there a way to make it clean in the jq command?

答案1

得分: 1

这里是一种使用正则表达式和 capture 的方法:

.events[].message | capture([
  "(?<date>[\\d-]+ [\\d:]+)",
  "(?<ip>[\\d.]+)",
  "(?<user>[^:]+)",
  "", "LOG", "duration",
  "(?<time>[\\d.]+)",
  "(?<query>.*)"
] | join("[^:]*: *"))
| [.date, .ip, .user, .time, .query | @html "<td>\(.)</td>"]
| "<tr>\(add)</tr>"
<tr><td>2023-07-06 03:55:24</td><td>11.11.11.11</td><td>testUser@postgres</td><td>2004.016</td><td>select pg_sleep(2);</td></tr>
<tr><td>2023-07-06 03:58:42</td><td>111.22.331.41</td><td>testService@postgres</td><td>2009.526</td><td>select pg_sleep(2);</td></tr>

演示


要添加一些简单的美化效果,你可以将最后一行替换为

| "<tr>\n\(map(" \(.)\n") | add)</tr>"
<tr>
  <td>2023-07-06 03:55:24</td>
  <td>11.11.11.11</td>
  <td>testUser@postgres</td>
  <td>2004.016</td>
  <td>select pg_sleep(2);</td>
</tr>
<tr>
  <td>2023-07-06 03:58:42</td>
  <td>111.22.331.41</td>
  <td>testService@postgres</td>
  <td>2009.526</td>
  <td>select pg_sleep(2);</td>
</tr>

演示

英文:

Here's one way using regular expressions with capture:

.events[].message | capture([
  &quot;(?&lt;date&gt;[\\d-]+ [\\d:]+)&quot;,
  &quot;(?&lt;ip&gt;[\\d.]+)&quot;,
  &quot;(?&lt;user&gt;[^:]+)&quot;,
  &quot;&quot;, &quot;LOG&quot;, &quot;duration&quot;,
  &quot;(?&lt;time&gt;[\\d.]+)&quot;,
  &quot;(?&lt;query&gt;.*)&quot;
] | join(&quot;[^:]*: *&quot;))
| [.date, .ip, .user, .time, .query | @html &quot;&lt;td&gt;\(.)&lt;/td&gt;&quot;]
| &quot;&lt;tr&gt;\(add)&lt;/tr&gt;&quot;
&lt;tr&gt;&lt;td&gt;2023-07-06 03:55:24&lt;/td&gt;&lt;td&gt;11.11.11.11&lt;/td&gt;&lt;td&gt;testUser@postgres&lt;/td&gt;&lt;td&gt;2004.016&lt;/td&gt;&lt;td&gt;select pg_sleep(2);&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;2023-07-06 03:58:42&lt;/td&gt;&lt;td&gt;111.22.331.41&lt;/td&gt;&lt;td&gt;testService@postgres&lt;/td&gt;&lt;td&gt;2009.526&lt;/td&gt;&lt;td&gt;select pg_sleep(2);&lt;/td&gt;&lt;/tr&gt;

Demo


To add some simple pretty-printing, you could replace the last line with

| &quot;&lt;tr&gt;\n\(map(&quot;  \(.)\n&quot;) | add)&lt;/tr&gt;&quot;
&lt;tr&gt;
  &lt;td&gt;2023-07-06 03:55:24&lt;/td&gt;
  &lt;td&gt;11.11.11.11&lt;/td&gt;
  &lt;td&gt;testUser@postgres&lt;/td&gt;
  &lt;td&gt;2004.016&lt;/td&gt;
  &lt;td&gt;select pg_sleep(2);&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;2023-07-06 03:58:42&lt;/td&gt;
  &lt;td&gt;111.22.331.41&lt;/td&gt;
  &lt;td&gt;testService@postgres&lt;/td&gt;
  &lt;td&gt;2009.526&lt;/td&gt;
  &lt;td&gt;select pg_sleep(2);&lt;/td&gt;
&lt;/tr&gt;

Demo

huangapple
  • 本文由 发表于 2023年7月6日 13:21:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76625723.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定