GoFrame 搭配 Grafana 讀取 Loki log

配置 Docker

建立一資料夾(loki)

新增三檔案 loki-config.yml,promtail-local-config.yml,docker-compose.yml

以下為三檔案內容

 

loki-config.yml

=============================

auth_enabled: false

 

server:

  http_listen_port: 3100

  grpc_listen_port: 9096

 

common:

  instance_addr: 127.0.0.1

  path_prefix: /tmp/loki

  storage:

    filesystem:

      chunks_directory: /tmp/loki/chunks

      rules_directory: /tmp/loki/rules

  replication_factor: 1

  ring:

    kvstore:

      store: inmemory

 

query_range:

  results_cache:

    cache:

      embedded_cache:

        enabled: true

        max_size_mb: 100

 

schema_config:

  configs:

    - from: 2020-10-24

      store: boltdb-shipper

      object_store: filesystem

      schema: v11

      index:

        prefix: index_

        period: 24h

 

ruler:

  alertmanager_url: http://localhost:9093

 

# By default, Loki will send anonymous, but uniquely-identifiable usage and configuration

# analytics to Grafana Labs. These statistics are sent to https://stats.grafana.org/

#

# Statistics help us better understand how Loki is used, and they show us performance

# levels for most users. This helps us prioritize features and documentation.

# For more information on what's sent, look at

# https://github.com/grafana/loki/blob/main/pkg/usagestats/stats.go

# Refer to the buildReport method to see what goes into a report.

#

# If you would like to disable reporting, uncomment the following lines:

#analytics:

#  reporting_enabled: false

=============================

 

promtail-local-config.yml

=============================

server:

  http_listen_port: 9080

  grpc_listen_port: 0

 

positions:

  filename: /tmp/positions.yaml

 

clients:

  - url: http://loki:3100/loki/api/v1/push

 

scrape_configs:

- job_name: system

  static_configs:

  - targets:

      - localhost

    labels:

      job: varlogs

      __path__: /var/log/*log

=============================

 

docker-compose.yml

=============================

version: "3"

 

networks:

  loki:

 

services:

  loki:

    image: grafana/loki:2.8.0

    ports:

      - "3100:3100"

    volumes:

      - ./loki-config.yml:/etc/loki/local-config.yml

    command: -config.file=/etc/loki/local-config.yml

    networks:

      - loki

 

  promtail:

    image: grafana/promtail:2.8.0

    volumes:

      - /var/log:/var/log

      - ./promtail-local-config.yml:/etc/promtail/config.yml:ro

    command: -config.file=/etc/promtail/config.yml

    networks:

      - loki

 

  grafana:

    environment:

      - GF_PATHS_PROVISIONING=/etc/grafana/provisioning

      - GF_AUTH_ANONYMOUS_ENABLED=true

      - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin

    entrypoint:

      - sh

      - -euc

      - |

        mkdir -p /etc/grafana/provisioning/datasources

        cat <<EOF > /etc/grafana/provisioning/datasources/ds.yaml

        apiVersion: 1

        datasources:

        - name: Loki

          type: loki

          access: proxy

          orgId: 1

          url: http://loki:3100

          basicAuth: false

          isDefault: true

          version: 1

          editable: false

        EOF

        /run.sh

    image: grafana/grafana:10.0.3

    ports:

      - "3000:3000"

    networks:

      - loki

=============================

 

啟動 Grafana

開啟 Docker Desktop

執行 docker compose up -d

 

設定 Grafana admin

瀏覽器開啟 http://localhost:3000/?orgId=1,點擊 Sign in

輸入預設帳/密 admin/admin, 後可以修改密碼

 

查詢 Loki log

重新登入後,點擊 Toggle Menu,並選擇 Explore

點擊 Label browser, 於畫面中點擊 job(1) 中的 varlogs 後,點擊 Show logs,結束設定,即可以看到結果

 

利用 postman 新增 log

使用 post,url 為 http://localhost:3100/loki/api/v1/push,使用 json 格式,發送以下內容

{

    "streams": [

        {

            "stream": {

                "label": "postman"

            },

            "values": [

                [

                    "1726476194219686912", //2024-09-16 16:43:14.210 時間戳

                    "fizzbuzz"

                ]

            ]

        }

    ]

}

 

若回傳結果為 204,即代表成功

 

查詢 postman 發送的 log

請回到網頁,點擊 code,輸入 {label="postman"},時間區間選 Last 2 days, 即可看到結果

 

設定 goFrame Hook

目前分兩隻程式,一隻主要loki hook,一隻 main, 用來測試 loki hook

程式內容如下

 

loki.go

=============================

package loki

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
    "time"

    "github.com/gogf/gf/v2/os/glog"
)

const (
    LOKI_LABEL = "go-demo"
    LOKI_APP   = "gavin-job"
)

type LokiHook struct {
    Logger *glog.Logger
    Label  string
    App    string
}

func (w *LokiHook) Write(p []byte) (n int, err error) {
    var (
        msg = string(p)
    )
    err = w.PostDataToLoki(msg)

    return w.Logger.Write(p)
}

type LokiEntry struct {
    Streams []struct {
        Stream map[string]string `json:"stream"`
        Values [][]string        `json:"values"`
    } `json:"streams"`
}

func (w *LokiHook) PostDataToLoki(msg string) error {
    stream := make(map[string]string, 0)
    //可以自由新增 key 值,方便 loki 查詢使用
    stream["label"] = w.Label
    stream["app"] = w.App //目前設定此來對應專案中 backend/app 中的應用
    valueList := make([][]string, 0)
    strTime := fmt.Sprintf("%v", time.Now().UnixNano())
    newRow := []string{strTime, msg}
    valueList = append(valueList, newRow)

    data := LokiEntry{
        Streams: []struct {
            Stream map[string]string `json:"stream"`
            Values [][]string        `json:"values"`
        }{
            {
                Stream: stream,
                Values: valueList,
            },
        },
    }

    jsonData, err := json.Marshal(data)
    if err != nil {
        return err
    }

    resp, err := http.Post("http://localhost:3100/loki/api/v1/push", "application/json", bytes.NewBuffer(jsonData))
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    return nil
}

=============================

 

main.go

=============================

package main

import (
    "context"

    "demo/loki/loki"

    "github.com/gogf/gf/v2/frame/g"
    "github.com/gogf/gf/v2/os/gctx"
    "github.com/gogf/gf/v2/os/glog"
)

func callFun(ctx context.Context, msg string) error {
    g.Log().Infof(ctx, "callFun msg:%v", msg)

    return nil
}

func main() {
    ctx := gctx.New()

    g.Log().SetWriter(&loki.LokiHook{
        Logger: glog.New(),
        Label:  loki.LOKI_LABEL,
        App:    loki.LOKI_APP,
    })

    g.Log().Infof(ctx, "run callFun")
    err := callFun(ctx, "hello, call fun test")
    if err != nil {
        g.Log().Errorf(ctx, "PostDataToLoki error:%v", err)
    } else {
        g.Log().Infof(ctx, "PostDataToLoki success")
    }

}

=============================

 

執行 go run main.go

 

查詢 goFrame 發送 log

點擊 Label browser 用選的,或是輸入 {app="gavin-job"},或是 {label="go-demo"},即可以看到結果

 

Note

Label browser, 是方便不用輸入可以直接用選的,結果會轉成輸入的值

 

參考來源

https://blog.yowko.com/docker-compose-grafana-loki/

 

文章標籤
全站熱搜
創作者介紹
創作者 狼翔月影 的頭像
狼翔月影

狼翔天地

狼翔月影 發表在 痞客邦 留言(0) 人氣(17)