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

GoFrame 搭配 Grafana 讀取 Loki log

 

設定 Grafana admin

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

GoFrame 搭配 Grafana 讀取 Loki log

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

GoFrame 搭配 Grafana 讀取 Loki log

 

查詢 Loki log

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

GoFrame 搭配 Grafana 讀取 Loki log

GoFrame 搭配 Grafana 讀取 Loki log

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

GoFrame 搭配 Grafana 讀取 Loki log

GoFrame 搭配 Grafana 讀取 Loki log

GoFrame 搭配 Grafana 讀取 Loki log

GoFrame 搭配 Grafana 讀取 Loki log

 

利用 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,即代表成功

GoFrame 搭配 Grafana 讀取 Loki log

 

查詢 postman 發送的 log

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

GoFrame 搭配 Grafana 讀取 Loki log

GoFrame 搭配 Grafana 讀取 Loki log

 

設定 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 搭配 Grafana 讀取 Loki log

 

查詢 goFrame 發送 log

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

GoFrame 搭配 Grafana 讀取 Loki log

GoFrame 搭配 Grafana 讀取 Loki log

GoFrame 搭配 Grafana 讀取 Loki log

 

Note

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

 

參考來源

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

 

arrow
arrow
    文章標籤
    goFrame Grafana Loki log go
    全站熱搜
    創作者介紹
    創作者 狼翔月影 的頭像
    狼翔月影

    狼翔天地

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