当前位置:网站首页>Echo framework: add API logging Middleware

Echo framework: add API logging Middleware

2022-06-24 02:15:00 Trespass

Introduce

Through a complete example , Based on Echo Add... To the microservices of the framework API Log Middleware .

What is a log interceptor / middleware ?

Log interceptors will be used for every API Request logging .

We will use rk-boot To start up Echo Microservices of the framework .

Please visit the following address for a complete tutorial :https://rkdocs.netlify.app/cn

install

go get github.com/rookie-ninja/rk-boot
go get github.com/rookie-ninja/rk-echo

Quick start

rk-boot By default, the following two open source libraries are integrated .

1. establish boot.yaml

boot.yaml The document describes Echo Original information of framework startup ,rk-boot By reading the boot.yaml To start up Echo.

In order to verify , We started at the same time commonService.commonService It contains a series of general API.

details : CommonService

---
echo:
  - name: greeter                   # Required, name of echo entry
    port: 8080                      # Required, port of echo entry
    enabled: true                   # Required, enable echo entry
    commonService:
      enabled: true                 # Optional, enable common service
    interceptors:
      loggingZap:
        enabled: true               # Optional, enable logging interceptor

2. establish main.go

package main

import (
	"context"
	"github.com/rookie-ninja/rk-boot"
	_ "github.com/rookie-ninja/rk-echo/boot"
)

// Application entrance.
func main() {
	// Create a new boot instance.
	boot := rkboot.NewBoot()

	// Bootstrap
	boot.Bootstrap(context.Background())

	// Wait for shutdown sig
	boot.WaitForShutdownSig(context.Background())
}

3. Folder structure

$ tree
.
├── boot.yaml
├── go.mod
├── go.sum
└── main.go

0 directories, 4 files

4. start-up main.go

$ go run main.go

5. verification

We send CommonService Self contained /rk/v1/healthy request .

$ curl -X GET localhost:8080/rk/v1/healthy
{"healthy":true}

EventLog The default output is to stdout.

The following log format is from rk-query , Users can also choose JSON Format , We'll talk about .

------------------------------------------------------------------------
endTime=2021-11-03T16:41:03.355739+08:00
startTime=2021-11-03T16:41:03.355582+08:00
elapsedNano=156642
timezone=CST
ids={"eventId":"7894acd4-5fd3-4809-aef7-dc4cfeb88bd2"}
app={"appName":"rk-demo","appVersion":"master-2c9c6fd","entryName":"greeter","entryType":"EchoEntry"}
env={"arch":"amd64","az":"*","domain":"*","hostname":"lark.local","localIP":"192.168.1.104","os":"darwin","realm":"*","region":"*"}
payloads={"apiMethod":"GET","apiPath":"/rk/v1/healthy","apiProtocol":"HTTP/1.1","apiQuery":"","userAgent":"curl/7.64.1"}
error={}
counters={}
pairs={}
timing={}
remoteAddr=localhost:49176
operation=/rk/v1/healthy
resCode=200
eventStatus=Ended
EOE

Change the log format

We can modify boot.yaml To modify the log format .

At present, we support json and console Two formats , The default is console.

By modifying the eventLoggerEncoding The value of is json, We can output the log as JSON Format .

echo:
  - name: greeter                    # Required, name of echo entry
    port: 8080                       # Required, port of echo entry
    enabled: true                    # Required, enable echo entry
    commonService:
      enabled: true                  # Optional, enable common service
    interceptors:
      loggingZap:
        enabled: true                # Optional, enable logging interceptor
        zapLoggerEncoding: "json"    # Override to json format, option: json or console
        eventLoggerEncoding: "json"  # Override to json format, option: json or console
{
    "endTime":"2021-11-03T16:42:16.265+0800",
    "startTime":"2021-11-03T16:42:16.265+0800",
    "elapsedNano":157537,
    "timezone":"CST",
    "ids":{
        "eventId":"420bd015-fb9f-415d-a95c-d01000520d08"
    },
    "app":{
        "appName":"rk-demo",
        "appVersion":"master-2c9c6fd",
        "entryName":"greeter",
        "entryType":"EchoEntry"
    },
    "env":{
        "arch":"amd64",
        "az":"*",
        "domain":"*",
        "hostname":"lark.local",
        "localIP":"192.168.1.104",
        "os":"darwin",
        "realm":"*",
        "region":"*"
    },
    "payloads":{
        "apiMethod":"GET",
        "apiPath":"/rk/v1/healthy",
        "apiProtocol":"HTTP/1.1",
        "apiQuery":"",
        "userAgent":"curl/7.64.1"
    },
    "error":{},
    "counters":{},
    "pairs":{},
    "timing":{},
    "remoteAddr":"localhost:53840",
    "operation":"/rk/v1/healthy",
    "eventStatus":"Ended",
    "resCode":"200"
}

Modify log path

By modifying the eventLoggerOutputPaths Value , You can specify an output path .

The log defaults to 1GB after , For cutting , And compress .

---
echo:
  - name: greeter                                     # Required, name of echo entry
    port: 8080                                        # Required, port of echo entry
    enabled: true                                     # Required, enable echo entry
    commonService:
      enabled: true                                   # Optional, enable common service
    interceptors:
      loggingZap:
        enabled: true                                 # Optional, enable logging interceptor
        zapLoggerOutputPaths: ["logs/app.log"]        # Override output paths
        eventLoggerOutputPaths: ["logs/event.log"]    # Override output paths
.
├── boot.yaml
├── go.mod
├── go.sum
├── logs
│   └── event.log
└── main.go

Concept

Log interceptor verified , Let's talk about it in detail rk-boot What are the functions of the provided log interceptors .

We need to understand two concepts in advance .

  • EventLogger
  • ZapLogger

ZapLogger

Used to record errors / Detailed log , This user can get RPC Called ZapLogger example , Log writing , Every RPC Of ZapLogger All instances contain the current RequestId.

2021-11-03T16:46:26.665+0800    INFO    boot/echo_entry.go:693  Bootstrapping EchoEntry.        {"eventId": "60abdcdb-5df7-43cd-b62d-c203c6b5afb4", "entryName": "greeter", "entryType": "EchoEntry", "port": 8080}

EventLogger

RK The starter puts each RPC Request as Event, And use rk-query Medium Event Type to log .

Field

details

endTime

End time

startTime

Starting time

elapsedNano

Event Time cost (Nanoseconds)

timezone

The time zone

ids

contain eventId, requestId and traceId. If the original data interceptor is activated , perhaps event.SetRequest() Called by user , new RequestId Will be used , meanwhile eventId And requestId It will be as like as two peas. . If the call chain interceptor is started ,traceId Will be recorded .

app

contain appName, appVersion, entryName, entryType.

env

contain arch, az, domain, hostname, localIP, os, realm, region. realm, region, az, domain Field . These fields come from system environment variables (REALM,REGION,AZ,DOMAIN). "*" Indicates that the environment variable is empty .

payloads

contain RPC Related information .

error

Contains errors .

counters

adopt event.SetCounter() To operate .

pairs

adopt event.AddPair() To operate .

timing

adopt event.StartTimer() and event.EndTimer() To operate .

remoteAddr

RPC Remote address .

operation

RPC name .

resCode

RPC Return code .

eventStatus

Ended perhaps InProgress

------------------------------------------------------------------------
endTime=2021-11-03T16:41:03.355739+08:00
startTime=2021-11-03T16:41:03.355582+08:00
elapsedNano=156642
timezone=CST
ids={"eventId":"7894acd4-5fd3-4809-aef7-dc4cfeb88bd2"}
app={"appName":"rk-demo","appVersion":"master-2c9c6fd","entryName":"greeter","entryType":"EchoEntry"}
env={"arch":"amd64","az":"*","domain":"*","hostname":"lark.local","localIP":"192.168.1.104","os":"darwin","realm":"*","region":"*"}
payloads={"apiMethod":"GET","apiPath":"/rk/v1/healthy","apiProtocol":"HTTP/1.1","apiQuery":"","userAgent":"curl/7.64.1"}
error={}
counters={}
pairs={}
timing={}
remoteAddr=localhost:49176
operation=/rk/v1/healthy
resCode=200
eventStatus=Ended
EOE

Log interceptor options

name

describe

type

The default value is

echo.interceptors.loggingZap.enabled

Start log interceptor

boolean

false

echo.interceptors.loggingZap.zapLoggerEncoding

Log format :json perhaps console

string

console

echo.interceptors.loggingZap.zapLoggerOutputPaths

Log file path

[]string

stdout

echo.interceptors.loggingZap.eventLoggerEncoding

Log format :json perhaps console

string

console

echo.interceptors.loggingZap.eventLoggerOutputPaths

Log file path

[]string

stdout

obtain RPC Log instance

every time RPC When asked to come in , The interceptor will RequestId( When the original data interceptor is started ) Inject into the log instance .

let me put it another way , every last RPC request , There will be a new Logger example . Let's see how for one RPC request , Record ZapLogger journal .

adopt rkechoctx.GetLogger(ctx) Method to obtain the log instance of this request .

func Greeter(ctx echo.Context) error {
	rkechoctx.GetLogger(ctx).Info("Request received")

	return ctx.JSON(http.StatusOK, &GreeterResponse{
		Message: fmt.Sprintf("Hello %s!", ctx.QueryParam("name")),
	})
}

The log was printed out !

2021-11-03T16:48:32.525+0800    INFO    basic/main.go:41        Request received        {"requestId": "c6468d01-4e03-4715-bcbb-2a7fa40a637c"}

modify Event

The log interceptor will RPC Request to create a Event example .

Users can add pairs,counters,errors.

adopt rkechoctx.GetEvent(ctx) Get this RPC Of Event example .

func Greeter(ctx echo.Context) error {
	event := rkechoctx.GetEvent(ctx)
	event.AddPair("key", "value")

	return ctx.JSON(http.StatusOK, &GreeterResponse{
		Message: fmt.Sprintf("Hello %s!", ctx.QueryParam("name")),
	})
}

Event It's added pairs={"key":"value"}!

------------------------------------------------------------------------
endTime=2021-11-03T16:49:17.982001+08:00
startTime=2021-11-03T16:49:17.981771+08:00
elapsedNano=230072
timezone=CST
ids={"eventId":"51aa7536-187b-41fb-aa32-f76b45522bc7","requestId":"51aa7536-187b-41fb-aa32-f76b45522bc7"}
app={"appName":"rk-demo","appVersion":"master-2c9c6fd","entryName":"greeter","entryType":"EchoEntry"}
env={"arch":"amd64","az":"*","domain":"*","hostname":"lark.local","localIP":"192.168.1.104","os":"darwin","realm":"*","region":"*"}
payloads={"apiMethod":"GET","apiPath":"/v1/greeter","apiProtocol":"HTTP/1.1","apiQuery":"","userAgent":"curl/7.64.1"}
error={}
counters={}
pairs={"key":"value"}
timing={}
remoteAddr=localhost:64301
operation=/v1/greeter
resCode=200
eventStatus=Ended
EOE
原网站

版权声明
本文为[Trespass ]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/11/20211103180440248F.html