当前位置:网站首页>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 .
- uber-go/zap As the underlying log Library .
- logrus Scroll as log .
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 interceptor2. 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
EOEChange 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
EOELog 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边栏推荐
- [new features] Tencent cloud lightweight ECS will soon support attaching data disks!!!
- Benchmarking Shopify? Similarities and differences between "two giants" of Chinese e-commerce SAAS and Weimeng
- Thorough and thorough analysis of factory method mode
- How to improve the success rate of trademark registration? How long does it take to register a trademark?
- [technical grass planting] how to batch check your server status? Cloud probe panel setup tutorial
- The United States offered 10million yuan to hunt down blackmail hackers and the energy industry became the "hardest hit" of phishing attacks | global network security hotspot
- A review of Nature Neuroscience: dynamic representation in networked nervous system
- An attempt to use Navicat tool to copy and export MySQL database data
- Is the trademark registered domain name legal? How do trademarks register domain names?
- Tencent music, slow down?
猜你喜欢

Leetcode969: pancake sorting (medium, dynamic programming)

If there are enumerations in the entity object, the conversion of enumerations can be carried out with @jsonvalue and @enumvalue annotations

How to fill in and register e-mail, and open mass mailing software for free

application. Yaml configuring multiple running environments

2020 language and intelligent technology competition was launched, and Baidu provided the largest Chinese data set

BIM model example

Introduction to development model + test model

layer 3 switch

Review of AI hotspots this week: the Gan compression method consumes less than 1/9 of the computing power, and the open source generator turns your photos into hand drawn photos

Advanced BOM tool intelligent packaging function
随机推荐
Analysis report on market development trends and innovation strategies of China's iron and steel industry 2022-2028
How to build video websites? What are the types of video websites?
An attempt to use Navicat tool to copy and export MySQL database data
Custom form dynamic form form designer process engine design scheme
What is a region name? Can a territory name be used for trademark registration?
No serializer found for class ** and no propert no properties discovered to create BeanSerializer
A multifunctional SSH Remote Server Management Tool
[technical grass planting] how to batch check your server status? Cloud probe panel setup tutorial
Implementing cos signature with postman
Leetcode969: pancake sorting (medium, dynamic programming)
How does Tencent cloud server build the official version of remote desktop computer to realize remote
Research Report on global and Chinese titanium concentrate market scale and investment prospects 2022-2028
Tencent cloud double 11 Live Room activity rules
Thorough and thorough analysis of factory method mode
Learn 30 programming languages in 1 minute
The difference between classless routing and classless routing
Set multiple print for batch generated barcodes
A complete collection of SQL commands. Each command has an example. Xiaobai can become a God after reading it!
Advanced BOM tool intelligent packaging function
LeetCode 1289. Descent path min and II