iT邦幫忙

0

【已自行解決】請問 Grafana Promtail 如何依 log 中的 http status code 標記 level

  • 分享至 

  • xImage

如下 log 和 Promtail 設定,想請問如何讓 HTTP_status_code 為 200、300系列時新增 level: info
400 時標記 warn
500 時標記 error 呢?

127.0.0.1 - - [01/Dec/2023:10:51:35 +0800] "GET /static/js/jquery.min.js HTTP/1.1" 500 86927
127.0.0.1 - - [01/Dec/2023:10:51:36 +0800] "GET /static/icons/icon1.png HTTP/1.1" 200 2847
127.0.0.1 - - [01/Dec/2023:10:51:36 +0800] "GET /static/1.png HTTP/1.1" 301 2847
server:
  http_listen_port: 9080  # Promtail 伺服器監聽的 HTTP 端口。
  grpc_listen_port: 0     # Promtail 伺服器監聽的 gRPC 端口。
  log_level: "debug"  # [debug, info, warn, error]

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://127.0.0.1:3100/loki/api/v1/push  
  
scrape_configs:
  - job_name: hello  # 作業名稱,可以自訂
    pipeline_stages:
      - multiline:
          firstline: '^(?P<ip>\d{1,3}(?:\.\d{1,3}){3}) - - \[(?P<time>\d{2}\/[a-zA-Z]{3}\/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4})\]'
          max_wait_time: 3s
          max_lines: 500
      - regex:
          expression: '(?P<ip>\d{1,3}(?:\.\d{1,3}){3}) - - \[(?P<time>\d{2}\/[a-zA-Z]{3}\/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4})\] "(?P<method>\w+) (?P<path>[^ ]+)(?: HTTP\/\d\.\d)?" (?P<HTTP_status_code>\d{3}) (?P<bytes>-|\d+)'
      - labels:
          HTTP_status_code:
      - timestamp:
          source: time # 來源時間欄位
          format: '01/Jan/2006:15:04:05 -0700' # 時間格式
          location: 'Asia/Taipei' # 時區
    static_configs:
      - targets:
          - localhost  # 收集 log 的目標主機
        labels:
          job: test_pj
          service: Apache
          server: Python
          __path__: /var/log/httpd/test_pj.location.com-access.log  # 現有的 log 文件路徑

      # - replace:
      #     expression: '(?P<HTTP_status_code>[23]\d{2}) \d+$'
      #     # source: "HTTP_status_code"
      #     replace: "info {$1} {HTTP_status_code}"

這邊有嘗試在 pipeline_stages 階段加入 replace 去處理,讓他變成先取代成有 level 的版本再貼上標籤,貼完後再用一次 replace 恢復原樣

不過發現他無法帶回原本的 HTTP_status_code 最終輸出會變成
127.0.0.1 - - [01/Dec/2023:15:17:21 +0800] "GET /static/icons/1.png HTTP/1.1" info {$1} {HTTP_status_code} 2847


此外根據 官網文件 pipeline_stages 應該也可以用 match 來標記 labels,可是下列方法卻失敗了,請問我誤會了什麼嗎/images/emoticon/emoticon06.gif

  - job_name: hello  # 作業名稱,可以自訂
    static_configs:
      - targets:
          - localhost 
        labels:
          job: test_pj
          service: Apache  
          server: Python
          __path__: /var/log/httpd/test_pj.location.com-access.log  # 現有的 log 文件路徑
    pipeline_stages:
      - multiline:
          firstline: '^(?P<ip>\d{1,3}(?:\.\d{1,3}){3}) - - \[(?P<time>\d{2}\/[a-zA-Z]{3}\/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4})\]'
          max_wait_time: 3s
          max_lines: 500
      - regex:
          expression: '(?P<ip>\d{1,3}(?:\.\d{1,3}){3}) - - \[(?P<time>\d{2}\/[a-zA-Z]{3}\/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4})\] "(?P<method>\w+) (?P<path>[^ ]+)(?: HTTP\/\d\.\d)?" (?P<HTTP_status_code>\d{3}) (?P<bytes>-|\d+)'
      # - replace:
      #     expression: '(?P<HTTP_status_code>[23]\d{2}) \d+$'
      #     # source: "HTTP_status_code"
      #     replace: "info {$1} {HTTP_status_code}"
      - labels:
          level:
          HTTP_status_code:
      # - replace:
      #     expression: 'level:info [info|warn|error]'
      #     replace: ''
      - timestamp:
          source: time # 來源時間欄位
          format: '01/Jan/2006:15:04:05 -0700' # 時間格式
          location: 'Asia/Taipei' # 時區
      - match:
          # 針對不同的 HTTP 狀態碼範圍設定不同的 level 標籤
          - selector: '{HTTP_status_code=~"[23]\\d{2}"}'
            stages:
              - labels:
                  level: "info"
          - selector: '{HTTP_status_code=~"4\\d{2}"}'
            stages:
              - labels:
                  level: "warn"
          - selector: '{HTTP_status_code=~"5\\d{2}"}'
            stages:
              - labels:
                  level: "error"

再麻煩指教了



結果自己摸出來了~ /images/emoticon/emoticon34.gif
有條件式的狀況用 template 處理是 OK der~

先用 regex 標記 HTTP_status_code_type(ex 2,3,4,5) label
再用 template 寫 if/else 標 level
然後 labeldrop 掉 HTTP_status_code_type label 就完成了!

    pipeline_stages:
      - multiline:
          firstline: '(?P<ip>\d{1,3}(?:\.\d{1,3}){3}) - - \[(?P<time>\d{2}\/[a-zA-Z]{3}\/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4})\]'
          max_wait_time: 3s
          max_lines: 500
      - regex:
          expression: '(?P<ip>\d{1,3}(?:\.\d{1,3}){3}) - - \[(?P<time>\d{2}\/[a-zA-Z]{3}\/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4})\] "(?P<method>\w+) (?P<path>[^ ]+)(?: HTTP\/\d\.\d)?" (?P<HTTP_status_code_type>\d)\d\d (?P<bytes>-|\d+)'
      - labels:
          HTTP_status_code_type:
      - timestamp:
          source: time # 來源時間欄位
          format: '02/Jan/2006:15:04:05 -0700' # 時間格式
          location: 'Asia/Taipei' # 時區
      - template:
          source: level
          template: |
            {{- if or (eq .HTTP_status_code_type "2") (eq .HTTP_status_code_type "3") -}}
            info
            {{- end -}}
            {{- if or (eq .HTTP_status_code_type "4") -}}
            warn
            {{- end -}}
            {{- if or (eq .HTTP_status_code_type "5") -}}
            error
            {{- end -}}
      - labels:
          level:
      - labeldrop:
          - HTTP_status_code_type
看更多先前的討論...收起先前的討論...
雷N iT邦研究生 1 級 ‧ 2023-12-03 22:28:56 檢舉
我在想你要的好像不是labels stage
而是static_labels來新增自定義label
https://grafana.com/docs/loki/latest/send-data/promtail/stages/static_labels/
we684123 iT邦研究生 5 級 ‧ 2023-12-04 09:04:26 檢舉
@雷N
謝謝回覆,不過不太一樣
static_labels 我是用來標記主機這種靜態不變的標籤的,像是來源 server 是哪一台,服務是哪一種,這些沒有辦法在 log 中找到但又重要且逆推來源(在 loki 查時)較困難時用的。像這種會依照 log 不同做不同標記的不太適合 static_labels 。

我是想要讓 unknow 標籤消失,這樣在真正未標記時較好及時察覺,所以才需要依 HTTP 狀態碼範圍設定不同的 level 標籤。
雷N iT邦研究生 1 級 ‧ 2023-12-04 13:41:12 檢舉
其實沒錯的, log level 在這筆上被判定是info, warn, error啥的就是靜態不變的了.
目的是讓
127.0.0.1 - - [01/Dec/2023:10:51:35 +0800] "GET /static/js/jquery.min.js HTTP/1.1" 500 86927
127.0.0.1 - - [01/Dec/2023:10:51:36 +0800] "GET /static/icons/icon1.png HTTP/1.1" 200 2847
127.0.0.1 - - [01/Dec/2023:10:51:36 +0800] "GET /static/1.png HTTP/1.1" 301 2847

把這些轉成結構化後
判斷status code 給不同level?
最終目的是這樣嗎xd
we684123 iT邦研究生 5 級 ‧ 2023-12-05 08:29:45 檢舉
@雷N 對~
we684123 iT邦研究生 5 級 ‧ 2023-12-06 14:56:02 檢舉
OK 搞定了,有條件式的狀況用 template 處理是 OK der~
先用 regex 標記 HTTP_status_code_type(ex 2,3,4,5) label
再用 template 寫 if/else 標 level
然後 labeldrop 掉 HTTP_status_code_type label 就完成了!
we684123 iT邦研究生 5 級 ‧ 2023-12-06 14:56:13 檢舉
(具體 code 看問答題目的最下面)
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友回答

立即登入回答