瀏覽代碼

zap log encoding

chris 2 年之前
父節點
當前提交
bf2822f75d

+ 4 - 2
.gitignore

@@ -1,3 +1,5 @@
-/storage/
+storage
 .idea
-*.log
+*.log
+deploy/docker-composer/conf
+deploy/docker-composer/data

+ 125 - 111
README.md

@@ -1,86 +1,39 @@
-# Nunu - An Elegant Golang Scaffold 
+# Nunu
+[中文介绍](https://github.com/go-nunu/nunu-layout-advanced/blob/main/README_zh.md)
 
-[简体中文介绍](https://github.com/go-nunu/nunu-layout-advanced/blob/main/README_zh.md)
 
 Nunu is an application scaffold based on Golang. Its name comes from the character Nunu in League of Legends, who is a little boy riding on the shoulder of a snowman. Like Nunu, This Project also stands on the shoulders of giants, and it is composed of various third-party libraries, including gin, gorm, wire, viper, zap, golang-jwt, go-redis, testify, sonyflake, go-survey, cobra, etc. These libraries are very popular in the Golang ecosystem, and their combination can help you quickly build an efficient and reliable application.
 
 ![Nunu](https://github.com/go-nunu/nunu/blob/main/.github/assets/banner.png)
 
+
 ## Features
 
-- **Gin**: A fast and lightweight Golang HTTP web framework.
-- **Gorm**: A powerful Golang ORM library that supports multiple databases.
-- **Wire**: A Golang compile-time dependency injection framework.
-- **Viper**: A Golang configuration management library that supports multiple file formats.
-- **Zap**: A fast and structured Golang logging library.
-- **Golang-jwt**: A Golang JWT authentication library.
-- **Go-redis**: A Golang Redis client library.
-- **Testify**: A Golang testing toolkit that provides assertions and mocking.
-- **Sonyflake**: A Golang distributed unique ID generator library.
-- **robfig-cron**: A great Crontab library.
+- **Gin**: https://github.com/gin-gonic/gin
+- **Gorm**: https://github.com/go-gorm/gorm
+- **Wire**: https://github.com/google/wire
+- **Viper**: https://github.com/spf13/viper
+- **Zap**: https://github.com/uber-go/zap
+- **Golang-jwt**: https://github.com/golang-jwt/jwt
+- **Go-redis**: https://github.com/go-redis/redis
+- **Testify**: https://github.com/stretchr/testify
+- **Sonyflake**: https://github.com/sony/sonyflake
+- **robfig-cron**: https://github.com/robfig/cron
 - More...
 ## Features
-* **Easy to use and customize**: Nunu provides a simple and intuitive API for building web applications. You can easily customize the application to meet specific needs.
-* **High performance and scalability**: Nunu is designed to be high-performance and scalable. It uses the latest technologies and best practices to ensure that your application can handle high traffic and large amounts of data.
-* **Secure and reliable**: Nunu places great emphasis on security. It provides built-in authentication, authorization, and encryption support. It also uses reliable third-party libraries to ensure that your application is secure and reliable.
+* **Low learning cost and customization**: Nunu encapsulates some popular libraries that Gopher is most familiar with. You can easily customize your application to meet specific needs.
+* **High performance and scalability**: Nunu aims to have high performance and scalability. It uses the latest technology and best practices to ensure that your application can handle high traffic and large amounts of data.
+* **Secure and reliable**: Nunu uses stable and reliable third-party libraries to ensure the security and reliability of your application.
 * **Modular and extensible**: Nunu is designed to be modular and extensible. You can easily add new features and functionality by using third-party libraries or writing your own modules.
-* **Well-documented and thoroughly tested**: Nunu is well-documented and thoroughly tested. It provides comprehensive documentation and examples to help you get started quickly. It also includes a suite of tests to ensure that your application works as expected.
-## Requirements
-To use Nunu, you need to install the following software on your system:
-
-* Golang 1.16 or higher
-* MySQL 5.7 or higher (optional)
-* Redis (optional)
-## Installation
-
-You can install Nunu with the following command:
-
-```bash
-go install github.com/go-nunu/nunu@latest
-```
-
-## Usage
-
-Using Nunu is very simple, you just need to follow these steps:
-
-1. Create a new project
-
-```bash
-nunu new my_project
-```
-
-2. Enter the project directory
+* **Complete documentation and testing**: Nunu has complete documentation and testing. It provides comprehensive documentation and examples to help you get started quickly. It also includes a set of test suites to ensure that your application works as expected.
 
-```bash
-cd my_project
-```
-
-3. Run the project
-
-```bash
-nunu run
-```
-
-4. Open http://localhost:8000/ in your browser, and you will see a welcome page.
+## Preview
+![Nunu](https://github.com/go-nunu/nunu/blob/main/.github/assets/iterm.png)
 
 ## Directory Structure
-
-The directory structure of Nunu is as follows:
-
-
 ```
 .
 ├── cmd
-│   ├── job
-│   │   ├── wire
-│   │   │   ├── wire.go
-│   │   │   └── wire_gen.go
-│   │   └── main.go
-│   ├── migration
-│   │   ├── wire
-│   │   │   ├── wire.go
-│   │   │   └── wire_gen.go
-│   │   └── main.go
 │   └── server
 │       ├── wire
 │       │   ├── wire.go
@@ -89,72 +42,133 @@ The directory structure of Nunu is as follows:
 ├── config
 │   ├── local.yml
 │   └── prod.yml
-├── deploy
-│   └── Dockerfile
 ├── internal
-│   ├── database
-│   │   └── migration.go
+│   ├── dao
+│   │   ├── dao.go
+│   │   └── user.go
 │   ├── handler
+│   │   ├── handler.go
 │   │   └── user.go
-│   ├── job
-│   │   └── job.go
 │   ├── middleware
-│   │   ├── cors.go
-│   │   ├── jwt.go
-│   │   ├── log.go
-│   │   └── sign.go
+│   │   └── cors.go
 │   ├── model
 │   │   └── user.go
 │   ├── provider
 │   │   └── provider.go
-│   ├── dao
-│   │   └── user.go
 │   ├── server
 │   │   └── http.go
 │   └── service
-│       ├── user.go
-│       └── user_test.go
+│       ├── service.go
+│       └── user.go
 ├── pkg
 │   ├── config
 │   │   └── config.go
-│   ├── db
-│   │   └── db.go
-│   ├── log
-│   │   ├── storage
-│   │   │   └── logs
-│   │   │       └── server.log
-│   │   ├── log.go
-│   │   └── log_test.go
-│   ├── md5
-│   │   └── md5.go
-│   ├── rdb
-│   │   └── redis.go
-│   ├── resp
-│   │   └── resp.go
-│   ├── sonyflake
-│   │   └── sonyflake.go
-│   └── uuid
-│       └── uuid.go
-├── storage
-│   └── logs
-│       └── server.log
-├── test
-│   └── server
-│       └── handler
-│           ├── storage
-│           │   └── logs
-│           │       └── server.log
-│           └── user_test.go
-├── web
-│   └── index.html
+│   ├── helper
+│   │   ├── md5
+│   │   │   └── md5.go
+│   │   ├── resp
+│   │   │   └── resp.go
+│   │   ├── sonyflake
+│   │   │   └── sonyflake.go
+│   │   └── uuid
+│   │       └── uuid.go
+│   ├── http
+│   │   └── http.go
+│   └── log
+│       └── log.go
 ├── LICENSE
 ├── README.md
 ├── README_zh.md
 ├── go.mod
 └── go.sum
+```
+
+
+This is the directory structure of a classic Golang project, which includes the following directories:
+
+- `cmd`: Contains the code for command-line applications, such as `main.go`.
+- `config`: Contains configuration files, such as `config.yaml`.
+- `internal`: Contains internal code that is not exposed externally.
+    - `dao`: Contains the code for Data Access Objects (DAOs).
+    - `handler`: Contains the code for HTTP request handlers.
+    - `middleware`: Contains the code for HTTP middleware.
+    - `model`: Contains the code for data models.
+    - `provider`: Contains the code for dependency injection.
+    - `server`: Contains the code for HTTP servers.
+    - `service`: Contains the code for business logic.
+- `pkg`: Contains reusable code that is exposed externally.
+    - `config`: Contains the code for reading configuration files.
+    - `helper`: Contains the code for helper functions.
+    - `http`: Contains HTTP-related code.
+    - `log`: Contains code related to logging.
+
+## Requirements
+To use Nunu, you need to install the following software on your system:
+
+* Golang 1.16 or higher
+* MySQL 5.7 or higher (optional)
+* Redis (optional)
+
+## Installation
+
+You can install Nunu using the following command:
+
+```bash
+go install github.com/go-nunu/nunu@latest
+```
+
+## Usage
+
+### Creating a New Project
+
+You can create a new Golang project using the following command:
+
+```bash
+nunu new projectName
+```
+
+This command will create a directory named `projectName` and generate an elegant Golang project structure within it.
 
+### Creating Components
 
+You can create handlers, services, and daos for your project using the following commands:
+
+```bash
+nunu create handler user
+nunu create service user
+nunu create dao user
+```
+or
+```
+nunu create hsd user
+```
+
+These commands will create components named `UserHandler`, `UserService`, and `UserDao`, respectively, and place them in the correct directories.
+
+### Starting the Project
+
+You can quickly start your project using the following command:
+
+```bash
+nunu run
 ```
 
+This command will start your Golang project and support file update hot reload.
+
+### Compiling wire.go
+
+You can quickly compile your `wire.go` file using the following command:
+
+```bash
+nunu wire
+```
+
+This command will compile your `wire.go` file and generate the required dependencies.
+
+## Contributing
+
+If you find any issues or have any improvement suggestions, please feel free to raise an issue or submit a pull request. We welcome your contributions!
+
 ## License
-Nunu is licensed under the MIT License. For more information, see the LICENSE file.
+
+Nunu is released under the MIT license. See [LICENSE](LICENSE) for more information.

+ 123 - 110
README_zh.md

@@ -1,84 +1,37 @@
-# Nunu - 一个优雅的 Golang 脚手架
-[英文介绍](https://github.com/go-nunu/nunu-layout-advanced/blob/main/README.md)
+# Nunu
+[英文介绍](https://github.com/go-nunu/nunu/blob/main/README.md)
 
-Nunu是一个基于Golang的应用脚手架,它的名字来自于英雄联盟中的角色,努努是一个骑在雪怪肩膀上的小男孩,和努努一样,该项目是站在巨人的肩膀上,它是由各种第三方库组合而成的,包括gin、gorm、wire、viper、zap、golang-jwt、go-redis、testify、sonyflake、go-survey、cobra等。这些库都是Golang生态中非常流行的库,它们的组合可以帮助你快速构建一个高效、可靠的应用程序。
+Nunu是一个基于Golang的应用脚手架,它的名字来自于英雄联盟中的游戏角色,一个骑在雪怪肩膀上的小男孩,和努努一样,该项目是站在巨人的肩膀上,它是由各种第三方库组合而成的,包括gin、gorm、wire、viper、zap、golang-jwt、go-redis、testify、sonyflake、go-survey、cobra等。这些库都是Golang生态中非常流行的库,它们的组合可以帮助你快速构建一个高效、可靠的应用程序。
 
 ![Nunu](https://github.com/go-nunu/nunu/blob/main/.github/assets/banner.png)
 
-## 功能
 
-- **Gin**: 一个快速和轻量级的 Golang HTTP web 框架。
-- **Gorm**: 一个强大的 Golang ORM 库,支持多种数据库。
-- **Wire**: 一个 Golang 编译时依赖注入框架。
-- **Viper**: 一个 Golang 配置管理库,支持多种文件格式。
-- **Zap**: 一个快速和结构化的 Golang 日志库。
-- **Golang-jwt**: 一个 Golang JWT 认证库。
-- **Go-redis**: 一个 Golang Redis 客户端库。
-- **Testify**: 一个 Golang 测试工具包,提供断言和模拟。
-- **Sonyflake**: 一个 Golang 分布式唯一 ID 生成器库。
-- **robfig-cron**: 一个很棒的Crontab库。
+## 功能
+- **Gin**: https://github.com/gin-gonic/gin
+- **Gorm**: https://github.com/go-gorm/gorm
+- **Wire**: https://github.com/google/wire
+- **Viper**: https://github.com/spf13/viper
+- **Zap**: https://github.com/uber-go/zap
+- **Golang-jwt**: https://github.com/golang-jwt/jwt
+- **Go-redis**: https://github.com/go-redis/redis
+- **Testify**: https://github.com/stretchr/testify
+- **Sonyflake**: https://github.com/sony/sonyflake
+- **robfig-cron**: https://github.com/robfig/cron
 - More...
 ## 特性
-* **易于使用和定制**:Nunu提供了一个简单直观的API,用于构建Web应用程序。您可以轻松定制应用程序以满足特定需求。
+* **超低学习成本和定制**:Nunu封装了Gopher最熟悉的一些流行库。您可以轻松定制应用程序以满足特定需求。
 * **高性能和可扩展性**:Nunu旨在具有高性能和可扩展性。它使用最新的技术和最佳实践,确保您的应用程序可以处理高流量和大量数据。
-* **安全可靠**:Nunu非常注重安全性。它提供了内置的身份验证、授权和加密支持。它还使用可靠的第三方库,确保您的应用程序安全可靠。
+* **安全可靠**:Nunu使用了稳定可靠的第三方库,确保您的应用程序安全可靠。
 * **模块化和可扩展**:Nunu旨在具有模块化和可扩展性。您可以通过使用第三方库或编写自己的模块轻松添加新功能和功能。
 * **文档完善和测试完备**:Nunu文档完善,测试完备。它提供了全面的文档和示例,帮助您快速入门。它还包括一套测试套件,确保您的应用程序按预期工作。
-## 要求
-要使用Nunu,您需要在系统上安装以下软件:
-
-* Golang 1.16或更高版本
-* MySQL5.7或更高版本(可选)
-* Redis(可选)
-## 安装
-
-你可以通过以下命令来安装Nunu:
-
-```bash
-go install github.com/go-nunu/nunu@latest
-```
-
-## 使用
-
-使用Nunu非常简单,你只需要按照以下步骤即可:
-
-1. 创建一个新的项目
-
-```bash
-nunu new my_project
-```
 
-2. 进入项目目录
-
-```bash
-cd my_project
-```
-
-3. 运行项目
-
-```bash
-nunu run
-```
-
-4. 在浏览器中打开 http://localhost:8000/ ,你将看到一个欢迎页面。
+## 预览
+![Nunu](https://github.com/go-nunu/nunu/blob/main/.github/assets/iterm.png)
 
 ## 目录结构
-
-Nunu的目录结构如下:
-
 ```
 .
 ├── cmd
-│   ├── job
-│   │   ├── wire
-│   │   │   ├── wire.go
-│   │   │   └── wire_gen.go
-│   │   └── main.go
-│   ├── migration
-│   │   ├── wire
-│   │   │   ├── wire.go
-│   │   │   └── wire_gen.go
-│   │   └── main.go
 │   └── server
 │       ├── wire
 │       │   ├── wire.go
@@ -87,72 +40,132 @@ Nunu的目录结构如下:
 ├── config
 │   ├── local.yml
 │   └── prod.yml
-├── deploy
-│   └── Dockerfile
 ├── internal
-│   ├── database
-│   │   └── migration.go
+│   ├── dao
+│   │   ├── dao.go
+│   │   └── user.go
 │   ├── handler
+│   │   ├── handler.go
 │   │   └── user.go
-│   ├── job
-│   │   └── job.go
 │   ├── middleware
-│   │   ├── cors.go
-│   │   ├── jwt.go
-│   │   ├── log.go
-│   │   └── sign.go
+│   │   └── cors.go
 │   ├── model
 │   │   └── user.go
 │   ├── provider
 │   │   └── provider.go
-│   ├── dao
-│   │   └── user.go
 │   ├── server
 │   │   └── http.go
 │   └── service
-│       ├── user.go
-│       └── user_test.go
+│       ├── service.go
+│       └── user.go
 ├── pkg
 │   ├── config
 │   │   └── config.go
-│   ├── db
-│   │   └── db.go
-│   ├── log
-│   │   ├── storage
-│   │   │   └── logs
-│   │   │       └── server.log
-│   │   ├── log.go
-│   │   └── log_test.go
-│   ├── md5
-│   │   └── md5.go
-│   ├── rdb
-│   │   └── redis.go
-│   ├── resp
-│   │   └── resp.go
-│   ├── sonyflake
-│   │   └── sonyflake.go
-│   └── uuid
-│       └── uuid.go
-├── storage
-│   └── logs
-│       └── server.log
-├── test
-│   └── server
-│       └── handler
-│           ├── storage
-│           │   └── logs
-│           │       └── server.log
-│           └── user_test.go
-├── web
-│   └── index.html
+│   ├── helper
+│   │   ├── md5
+│   │   │   └── md5.go
+│   │   ├── resp
+│   │   │   └── resp.go
+│   │   ├── sonyflake
+│   │   │   └── sonyflake.go
+│   │   └── uuid
+│   │       └── uuid.go
+│   ├── http
+│   │   └── http.go
+│   └── log
+│       └── log.go
 ├── LICENSE
 ├── README.md
 ├── README_zh.md
 ├── go.mod
 └── go.sum
+```
+
+这是一个经典的Golang 项目的目录结构,包含以下目录:
+
+- `cmd`:存放命令行应用的代码,例如 `main.go`。
+- `config`:存放配置文件,例如 `config.yaml`。
+- `internal`:存放项目内部的代码,不对外暴露。
+  - `dao`:存放数据访问对象(Data Access Object)的代码。
+  - `handler`:存放 HTTP 请求处理器的代码。
+  - `middleware`:存放 HTTP 中间件的代码。
+  - `model`:存放数据模型的代码。
+  - `provider`:存放依赖注入的代码。
+  - `server`:存放 HTTP 服务器的代码。
+  - `service`:存放业务逻辑的代码。
+- `pkg`:存放可重用的代码,对外暴露。
+  - `config`:存放读取配置文件的代码。
+  - `helper`:存放辅助函数的代码。
+  - `http`:存放 HTTP 相关的代码。
+  - `log`:存放日志相关的代码。
 
+## 要求
+要使用Nunu,您需要在系统上安装以下软件:
 
+* Golang 1.16或更高版本
+* MySQL5.7或更高版本(可选)
+* Redis(可选)
+
+
+## 安装
+
+您可以通过以下命令安装Nunu:
+
+```bash
+go install github.com/go-nunu/nunu@latest
 ```
 
+## 使用
+
+### 创建新项目
+
+您可以使用以下命令创建一个新的Golang项目:
+
+```bash
+nunu new projectName
+```
+
+此命令将创建一个名为`projectName`的目录,并在其中生成一个优雅的Golang项目结构。
+
+### 创建组件
+
+您可以使用以下命令为项目创建handler、service和dao等组件:
+
+```bash
+nunu create handler user
+nunu create service user
+nunu create dao user
+```
+或
+```
+nunu create hsd user
+```
+这些命令将分别创建一个名为`UserHandler`、`UserService`和`UserDao`的组件,并将它们放置在正确的目录中。
+
+### 启动项目
+
+您可以使用以下命令快速启动项目:
+
+```bash
+nunu run
+```
+
+此命令将启动您的Golang项目,并支持文件更新热重启。
+
+### 编译wire.go
+
+您可以使用以下命令快速编译`wire.go`:
+
+```bash
+nunu wire
+```
+
+此命令将编译您的`wire.go`文件,并生成所需的依赖项。
+
+## 贡献
+
+如果您发现任何问题或有任何改进意见,请随时提出问题或提交拉取请求。我们非常欢迎您的贡献!
+
 ## 许可证
-Nunu根据MIT许可证获得许可。有关更多信息,请参见LICENSE文件。
+
+Nunu是根据MIT许可证发布的。有关更多信息,请参见[LICENSE](LICENSE)文件。

+ 3 - 4
config/local.yml

@@ -18,10 +18,9 @@ data:
     write_timeout: 0.2s
 
 log:
-  # log配置,stdout在debug级别才会开启
-  # 生产环境采用json结构化日志,方便elk采集
-  log_level: "debug"           # 高级别会过滤掉低级别的日志,debug<info<warn<error<fatal<panic
-  log_file_name: "./storage/logs/server.log"  #zap 业务日志路径
+  log_level: debug
+  encoding: console           # json or console
+  log_file_name: "./storage/logs/server.log"
   max_backups: 30              # 日志文件最多保存多少个备份
   max_age: 7                   #  文件最多保存多少天
   max_size: 1024               #  每个日志文件保存的最大尺寸 单位:M

+ 6 - 7
config/prod.yml

@@ -1,4 +1,4 @@
-env: prod
+env: local
 http:
   port: 8000
 security:
@@ -9,19 +9,18 @@ security:
     key: 1234
 data:
   mysql:
-    dns: root:123456@tcp(127.0.0.1:3306)/gin-db?charset=utf8mb4&parseTime=True&loc=Local
+    user: root:123456@tcp(127.0.0.1:3380)/user?charset=utf8mb4&parseTime=True&loc=Local
   redis:
     addr: 127.0.0.1:6350
-    password: "123456"
+    password: ""
     db: 0
     read_timeout: 0.2s
     write_timeout: 0.2s
 
 log:
-  # log配置,stdout在debug级别才会开启
-  # 生产环境采用json结构化日志,方便elk采集
-  log_level: "debug"           # 高级别会过滤掉低级别的日志,debug<info<warn<error<fatal<panic
-  log_file_name: "./storage/logs/server.log"  #zap 业务日志路径
+  log_level: info
+  encoding: json           # json or console
+  log_file_name: "./storage/logs/server.log"
   max_backups: 30              # 日志文件最多保存多少个备份
   max_age: 7                   #  文件最多保存多少天
   max_size: 1024               #  每个日志文件保存的最大尺寸 单位:M

+ 6 - 21
internal/middleware/jwt.go

@@ -50,19 +50,12 @@ func (j *JWT) ParseToken(tokenString string) (*MyCustomClaims, error) {
 	}
 }
 
-func NoAuth(log *log.Logger) gin.HandlerFunc {
-	return func(ctx *gin.Context) {
-		log.WithContext(ctx).Info("建立请求")
-		ctx.Next()
-	}
-}
-
 // StrictAuth 严格权限
-func StrictAuth(j *JWT, log *log.Logger) gin.HandlerFunc {
+func StrictAuth(j *JWT, logger *log.Logger) gin.HandlerFunc {
 	return func(ctx *gin.Context) {
 		tokenString := ctx.Request.Header.Get("Authorization")
 		if tokenString == "" {
-			log.WithContext(ctx).Warn("请求未携带token,无权限访问", zap.Any("data", map[string]interface{}{
+			logger.WithContext(ctx).Warn("请求未携带token,无权限访问", zap.Any("data", map[string]interface{}{
 				"url":    ctx.Request.URL,
 				"params": ctx.Params,
 			}))
@@ -74,7 +67,7 @@ func StrictAuth(j *JWT, log *log.Logger) gin.HandlerFunc {
 		// parseToken 解析token包含的信息
 		claims, err := j.ParseToken(tokenString)
 		if err != nil {
-			log.WithContext(ctx).Error("token error", zap.Any("data", map[string]interface{}{
+			logger.WithContext(ctx).Error("token error", zap.Any("data", map[string]interface{}{
 				"url":    ctx.Request.URL,
 				"params": ctx.Params,
 			}))
@@ -85,12 +78,12 @@ func StrictAuth(j *JWT, log *log.Logger) gin.HandlerFunc {
 
 		// 继续交由下一个路由处理,并将解析出的信息传递下去
 		ctx.Set("claims", claims)
-		recoveryLoggerFunc(ctx, log)
+		recoveryLoggerFunc(ctx, logger)
 		ctx.Next()
 	}
 }
 
-func NoStrictAuth(j *JWT, log *log.Logger) gin.HandlerFunc {
+func NoStrictAuth(j *JWT, logger *log.Logger) gin.HandlerFunc {
 	return func(ctx *gin.Context) {
 		tokenString := ctx.Request.Header.Get("Authorization")
 		if tokenString == "" {
@@ -100,7 +93,6 @@ func NoStrictAuth(j *JWT, log *log.Logger) gin.HandlerFunc {
 			tokenString = ctx.Query("accessToken")
 		}
 		if tokenString == "" {
-			log.WithContext(ctx).Info("建立请求")
 			ctx.Next()
 			return
 		}
@@ -108,25 +100,18 @@ func NoStrictAuth(j *JWT, log *log.Logger) gin.HandlerFunc {
 		// parseToken 解析token包含的信息
 		claims, err := j.ParseToken(tokenString)
 		if err != nil {
-			log.WithContext(ctx).Info("建立请求")
 			ctx.Next()
 			return
 		}
 
 		// 继续交由下一个路由处理,并将解析出的信息传递下去
 		ctx.Set("claims", claims)
-		recoveryLoggerFunc(ctx, log)
+		recoveryLoggerFunc(ctx, logger)
 		ctx.Next()
 	}
 }
 
 func recoveryLoggerFunc(ctx *gin.Context, logger *log.Logger) {
-	if ctx.Request.URL.Path == "/cos/object" && ctx.Request.Method == "POST" {
-		return
-	}
 	userInfo := ctx.MustGet("claims").(*MyCustomClaims)
 	logger.NewContext(ctx, zap.Int64("UserId", userInfo.UserId))
-	logger.WithContext(ctx).Info("建立请求")
-
-	// 统计
 }

+ 10 - 30
internal/middleware/log.go

@@ -2,7 +2,6 @@ package middleware
 
 import (
 	"bytes"
-	"context"
 	"encoding/json"
 	"fmt"
 	"github.com/gin-gonic/gin"
@@ -12,35 +11,29 @@ import (
 	"go.uber.org/zap"
 	"io"
 	"strconv"
-	"strings"
 	"time"
 )
 
-func GinContextToContextMiddleware() gin.HandlerFunc {
-	return func(c *gin.Context) {
-		ctx := context.WithValue(c.Request.Context(), "GinContextKey", c)
-		c.Request = c.Request.WithContext(ctx)
-		c.Next()
-	}
-}
-func RequestLogMiddleware(log *log.Logger) gin.HandlerFunc {
+func RequestLogMiddleware(logger *log.Logger) gin.HandlerFunc {
 	return func(ctx *gin.Context) {
+
 		// 每次请求都初始化一次配置
 		trace := md5.Md5(uuid.GenUUID())
-		log.NewContext(ctx, zap.String("trace", trace))
-		log.NewContext(ctx, zap.String("request_method", ctx.Request.Method))
+		logger.NewContext(ctx, zap.String("trace", trace))
+		logger.NewContext(ctx, zap.String("request_method", ctx.Request.Method))
 		headers, _ := json.Marshal(ctx.Request.Header)
-		log.NewContext(ctx, zap.String("request_headers", string(headers)))
-		log.NewContext(ctx, zap.String("request_url", ctx.Request.URL.String()))
+		logger.NewContext(ctx, zap.String("request_headers", string(headers)))
+		logger.NewContext(ctx, zap.String("request_url", ctx.Request.URL.String()))
 		if ctx.Request.Body != nil {
 			bodyBytes, _ := ctx.GetRawData()
 			ctx.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) // 关键点
-			log.NewContext(ctx, zap.String("request_params", string(bodyBytes)))
+			logger.NewContext(ctx, zap.String("request_params", string(bodyBytes)))
 		}
+		logger.WithContext(ctx).Info("Request")
 		ctx.Next()
 	}
 }
-func ResponseLogMiddleware(log *log.Logger) gin.HandlerFunc {
+func ResponseLogMiddleware(logger *log.Logger) gin.HandlerFunc {
 	return func(ctx *gin.Context) {
 		blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: ctx.Writer}
 		ctx.Writer = blw
@@ -48,20 +41,7 @@ func ResponseLogMiddleware(log *log.Logger) gin.HandlerFunc {
 		ctx.Next()
 		duration := int(time.Since(startTime).Milliseconds())
 		ctx.Header("X-Response-Time", strconv.Itoa(duration))
-		if ctx.Request.URL.Path == "/cos/object" && ctx.Request.Method == "POST" {
-			return
-		}
-		if strings.Contains(ctx.Request.URL.Path, "storage") {
-			return
-		}
-		log.WithContext(ctx).Info("响应返回", zap.Any("response_body", blw.body.String()), zap.Any("time", fmt.Sprintf("%sms", strconv.Itoa(duration))))
-		statusCode := ctx.Writer.Status()
-		fmt.Println(statusCode)
-		//if statusCode >= 400 {
-		//ok this is an request with error, let's make a record for it
-		// now print body (or log in your preferred way)
-		//fmt.Println("Response body: " + blw.body.String())
-		//}
+		logger.WithContext(ctx).Info("Response", zap.Any("response_body", blw.body.String()), zap.Any("time", fmt.Sprintf("%sms", strconv.Itoa(duration))))
 	}
 }
 

+ 1 - 1
internal/middleware/sign.go

@@ -11,7 +11,7 @@ import (
 	"strings"
 )
 
-func SignMiddleware(log *log.Logger, conf *viper.Viper) gin.HandlerFunc {
+func SignMiddleware(logger *log.Logger, conf *viper.Viper) gin.HandlerFunc {
 	return func(ctx *gin.Context) {
 		timestamp, ok := ctx.Request.Header["Timestamp"]
 		if !ok || len(timestamp) == 0 {

+ 18 - 17
internal/server/http.go

@@ -9,40 +9,41 @@ import (
 )
 
 func NewServerHTTP(
-	log *log.Logger,
+	logger *log.Logger,
 	jwt *middleware.JWT,
 	userHandler *handler.UserHandler,
 ) *gin.Engine {
 	gin.SetMode(gin.ReleaseMode)
 	r := gin.Default()
+
 	r.Use(
-		middleware.RequestLogMiddleware(log),
 		middleware.CORSMiddleware(),
-		middleware.NoAuth(log),
-		middleware.ResponseLogMiddleware(log),
+		middleware.ResponseLogMiddleware(logger),
 		//middleware.SignMiddleware(log),
 	)
-	r.GET("/", func(ctx *gin.Context) {
-		resp.HandleSuccess(ctx, map[string]interface{}{
-			"say": "Hi Nunu!",
-		})
-	})
 
-	noAuthRouter := r.Use(middleware.NoAuth(log))
+	// 无权限路由
+	noAuthRouter := r.Group("/").Use(middleware.RequestLogMiddleware(logger))
 	{
 		noAuthRouter.GET("/user", userHandler.GetUserById)
-
-	}
-	// 严格权限路由
-	strictAuthRouter := r.Use(middleware.StrictAuth(jwt, log))
-	{
-		strictAuthRouter.PUT("/user", userHandler.UpdateUser)
+		noAuthRouter.GET("/", func(ctx *gin.Context) {
+			logger.WithContext(ctx).Info("hello")
+			resp.HandleSuccess(ctx, map[string]interface{}{
+				"say": "Hi Nunu!",
+			})
+		})
 	}
 	// 非严格权限路由
-	noStrictAuthRouter := r.Use(middleware.NoStrictAuth(jwt, log))
+	noStrictAuthRouter := r.Group("/").Use(middleware.NoStrictAuth(jwt, logger), middleware.RequestLogMiddleware(logger))
 	{
 		noStrictAuthRouter.POST("/user", userHandler.CreateUser)
 	}
 
+	// 严格权限路由
+	strictAuthRouter := r.Group("/").Use(middleware.StrictAuth(jwt, logger), middleware.RequestLogMiddleware(logger))
+	{
+		strictAuthRouter.PUT("/user", userHandler.UpdateUser)
+	}
+
 	return r
 }

+ 41 - 38
pkg/log/log.go

@@ -46,51 +46,54 @@ func initZap(conf *viper.Viper) *Logger {
 		MaxAge:     conf.GetInt("log.max_age"),     // 文件最多保存多少天
 		Compress:   conf.GetBool("log.compress"),   // 是否压缩
 	}
-	// 是否 DEBUG
-	if conf.GetString("env") != "prod" {
-		core := zapcore.NewCore(
-			zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
-				TimeKey:        "ts",
-				LevelKey:       "level",
-				NameKey:        "Logger",
-				CallerKey:      "caller",
-				MessageKey:     "msg",
-				StacktraceKey:  "stacktrace",
-				LineEnding:     zapcore.DefaultLineEnding,
-				EncodeLevel:    zapcore.LowercaseColorLevelEncoder,
-				EncodeTime:     timeEncoder,
-				EncodeDuration: zapcore.SecondsDurationEncoder,
-				EncodeCaller:   zapcore.FullCallerEncoder,
-			}), // 编码器配置
-			//zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)),      // 打印到控制台
-			zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 打印到控制台和文件
-			level, // 日志级别
-		)
-
-		// 开启开发模式,堆栈跟踪
-		caller := zap.AddCaller()
-		// 开启文件及行号
-		development := zap.Development()
-		// 设置初始化字段
-		//filed := zap.Fields(zap.String("serviceName", "serviceName"))
-		// 构造日志
-		return &Logger{zap.New(core, caller, development, zap.AddStacktrace(zap.ErrorLevel))}
 
+	var encoder zapcore.Encoder
+	if conf.GetString("log.encoding") == "console" {
+		encoder = zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
+			TimeKey:        "ts",
+			LevelKey:       "level",
+			NameKey:        "Logger",
+			CallerKey:      "caller",
+			MessageKey:     "msg",
+			StacktraceKey:  "stacktrace",
+			LineEnding:     zapcore.DefaultLineEnding,
+			EncodeLevel:    zapcore.LowercaseColorLevelEncoder,
+			EncodeTime:     timeEncoder,
+			EncodeDuration: zapcore.SecondsDurationEncoder,
+			EncodeCaller:   zapcore.FullCallerEncoder,
+		})
 	} else {
-		encoderConfig := zap.NewProductionEncoderConfig()
-		return &Logger{zap.New(zapcore.NewCore(
-			zapcore.NewJSONEncoder(encoderConfig),                                           // 编码器配置(生产环境使用json)
-			zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 打印到控制台和文件
-			level, // 日志级别
-		), zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
-
+		encoder = zapcore.NewJSONEncoder(zapcore.EncoderConfig{
+			TimeKey:        "ts",
+			LevelKey:       "level",
+			NameKey:        "logger",
+			CallerKey:      "caller",
+			FunctionKey:    zapcore.OmitKey,
+			MessageKey:     "msg",
+			StacktraceKey:  "stacktrace",
+			LineEnding:     zapcore.DefaultLineEnding,
+			EncodeLevel:    zapcore.LowercaseLevelEncoder,
+			EncodeTime:     zapcore.EpochTimeEncoder,
+			EncodeDuration: zapcore.SecondsDurationEncoder,
+			EncodeCaller:   zapcore.ShortCallerEncoder,
+		})
 	}
+	core := zapcore.NewCore(
+		encoder, // 编码器配置
+		zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 打印到控制台和文件
+		level, // 日志级别
+	)
+	if conf.GetString("env") != "prod" {
+		return &Logger{zap.New(core, zap.Development(), zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
+	}
+	return &Logger{zap.New(core, zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
+
 }
 
 // 自定义时间编码器
 func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
-	enc.AppendString(t.Format("2006-01-02 15:04:05"))
-	//enc.AppendString(t.Format("2006-01-02 15:04:05.000000000"))
+	//enc.AppendString(t.Format("2006-01-02 15:04:05"))
+	enc.AppendString(t.Format("2006-01-02 15:04:05.000000000"))
 }
 
 // NewContext 给指定的context添加字段

+ 0 - 97
test/server/handler/storage/logs/server.log

@@ -1,97 +0,0 @@
-2023-06-03 00:27:49	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:33	start
-2023-06-03 00:27:49	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "0bdb3695c4ca3381d3cbbadf5b0904a2", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"actionType\":1,\"phone\":\"18502100065\"}"}
-2023-06-03 00:27:49	info	/Users/chris/Projects/stu/gin-starter/internal/handler/user.go:28	GetUserByID	{"sonyflake": 463376085304737894}
-2023-06-03 00:27:49	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "0bdb3695c4ca3381d3cbbadf5b0904a2", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"actionType\":1,\"phone\":\"18502100065\"}", "response_body": "{\"code\":1,\"message\":\"record not found\",\"data\":{}}", "time": "2ms"}
-2023-06-03 00:28:18	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:33	start
-2023-06-03 00:28:18	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "f0bba6b5830095ae2f7e56e9d7c6897e", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"actionType\":1,\"phone\":\"18502100065\"}"}
-2023-06-03 00:28:18	info	/Users/chris/Projects/stu/gin-starter/internal/handler/user.go:28	GetUserByID	{"sonyflake": 463376133757337702}
-2023-06-03 00:28:18	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "f0bba6b5830095ae2f7e56e9d7c6897e", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"actionType\":1,\"phone\":\"18502100065\"}", "response_body": "{\"code\":1,\"message\":\"record not found\",\"data\":{}}", "time": "2ms"}
-2023-06-03 00:40:03	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
-2023-06-03 00:40:03	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "5d1b363586f1d709bf1c4c616dbf5a42", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"actionType\":1,\"phone\":\"18502100065\"}"}
-2023-06-03 00:40:03	info	/Users/chris/Projects/stu/gin-starter/internal/handler/user.go:28	GetUserByID	{"sonyflake": 463377317238931558}
-2023-06-03 00:40:03	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "5d1b363586f1d709bf1c4c616dbf5a42", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"actionType\":1,\"phone\":\"18502100065\"}", "response_body": "{\"code\":1,\"message\":\"record not found\",\"data\":{}}", "time": "2ms"}
-2023-06-03 00:48:11	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
-2023-06-03 00:48:12	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "7d6f948b1edb1b283b859addb92022b9", "request_method": "POST", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"email\":\"5303221@gmail.com\",\"username\":\"test\"}"}
-2023-06-03 00:48:12	info	/Users/chris/Projects/stu/gin-starter/internal/handler/user.go:47	CreateUser	{"user": {"ID":1,"CreatedAt":"2023-06-03T00:48:12.007+08:00","UpdatedAt":"2023-06-03T00:48:12.007+08:00","DeletedAt":null,"Username":"test","Email":"5303221@gmail.com"}}
-2023-06-03 00:48:21	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "7d6f948b1edb1b283b859addb92022b9", "request_method": "POST", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"email\":\"5303221@gmail.com\",\"username\":\"test\"}", "response_body": "{\"code\":0,\"message\":\"success\",\"data\":{\"ID\":1,\"CreatedAt\":\"2023-06-03T00:48:12.007+08:00\",\"UpdatedAt\":\"2023-06-03T00:48:12.007+08:00\",\"DeletedAt\":null,\"Username\":\"test\",\"Email\":\"5303221@gmail.com\"}}", "time": "9827ms"}
-2023-06-03 00:48:51	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
-2023-06-03 00:48:51	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "fde7e0f0d6c2d72558de89ba9270c04b", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=aaa"}
-2023-06-03 00:48:51	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "fde7e0f0d6c2d72558de89ba9270c04b", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=aaa", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
-2023-06-03 00:49:13	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
-2023-06-03 00:49:13	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "12e4b2be61b6e0954a53a1a7d6e63ad5", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
-2023-06-03 00:49:13	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "12e4b2be61b6e0954a53a1a7d6e63ad5", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
-2023-06-03 00:49:36	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
-2023-06-03 00:49:36	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "1a5cccc20a9097ddb3d2e98b0fa38634", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
-2023-06-03 00:49:36	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "1a5cccc20a9097ddb3d2e98b0fa38634", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
-2023-06-03 00:50:09	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
-2023-06-03 00:50:09	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "9d13d05958c821ef4b14c855fea94854", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
-2023-06-03 00:50:09	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "9d13d05958c821ef4b14c855fea94854", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
-2023-06-03 00:50:44	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
-2023-06-03 00:50:44	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "ed2ccae0fa4accdc317ee0f6bb036312", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
-2023-06-03 00:50:44	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "ed2ccae0fa4accdc317ee0f6bb036312", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
-2023-06-03 00:50:53	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
-2023-06-03 00:50:53	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "a6dc94353e52f6ca91b7c50df42e9750", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
-2023-06-03 00:50:53	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "a6dc94353e52f6ca91b7c50df42e9750", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
-2023-06-03 00:51:31	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
-2023-06-03 00:51:31	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "332e61758a39c529cfcdd36de4e7a47c", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
-2023-06-03 00:51:31	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "332e61758a39c529cfcdd36de4e7a47c", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
-2023-06-03 00:51:36	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
-2023-06-03 00:51:36	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "a09398a82736c1127647996a007a2658", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
-2023-06-03 00:57:46	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
-2023-06-03 00:57:46	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "996290c5fe5fd7700a6f4298612a4c8a", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user"}
-2023-06-03 00:58:34	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "996290c5fe5fd7700a6f4298612a4c8a", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "47328ms"}
-2023-06-03 00:58:38	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
-2023-06-03 00:58:38	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "57945bf50e811ef287e0cc7c92d665ea", "request_method": "GET", "request_headers": "{}", "request_url": "/user?email=5303221@gmail.com"}
-2023-06-03 00:58:43	info	/Users/chris/Projects/stu/gin-starter/internal/handler/user.go:60	GetUserByID	{"user": {"ID":1,"CreatedAt":"2023-06-03T00:48:12.007+08:00","UpdatedAt":"2023-06-03T00:48:12.007+08:00","DeletedAt":null,"Username":"test","Email":"5303221@gmail.com"}}
-2023-06-03 00:58:43	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "57945bf50e811ef287e0cc7c92d665ea", "request_method": "GET", "request_headers": "{}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":0,\"message\":\"success\",\"data\":{\"ID\":1,\"CreatedAt\":\"2023-06-03T00:48:12.007+08:00\",\"UpdatedAt\":\"2023-06-03T00:48:12.007+08:00\",\"DeletedAt\":null,\"Username\":\"test\",\"Email\":\"5303221@gmail.com\"}}", "time": "5315ms"}
-2023-06-05 15:52:00	info	/Users/chris/Projects/stu/nunu-layout/test/server/handler/user_test.go:47	start
-2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:55	建立请求	{"trace": "856fe8165f39ab3d7734fca386f74b1c", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
-2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:55	建立请求	{"trace": "856fe8165f39ab3d7734fca386f74b1c", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
-2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/internal/middleware/log.go:57	响应返回	{"trace": "856fe8165f39ab3d7734fca386f74b1c", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
-2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/test/server/handler/user_test.go:47	start
-2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:55	建立请求	{"trace": "66ab47224d8602f41e275df08e55582f", "request_method": "POST", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"]}", "request_url": "/user", "request_params": "{\"email\":\"5303221@gmail.com\",\"username\":\"test\"}"}
-2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:55	建立请求	{"trace": "66ab47224d8602f41e275df08e55582f", "request_method": "POST", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"]}", "request_url": "/user", "request_params": "{\"email\":\"5303221@gmail.com\",\"username\":\"test\"}"}
-2023-06-05 15:52:04	error	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:77	token error	{"trace": "66ab47224d8602f41e275df08e55582f", "request_method": "POST", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"]}", "request_url": "/user", "request_params": "{\"email\":\"5303221@gmail.com\",\"username\":\"test\"}", "data": {"params":null,"url":{"Scheme":"","Opaque":"","User":null,"Host":"","Path":"/user","RawPath":"","OmitHost":false,"ForceQuery":false,"RawQuery":"","Fragment":"","RawFragment":""}}}
-github.com/go-nunu/nunu-layout-advanced/internal/middleware.StrictAuth.func1
-	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:77
-github.com/gin-gonic/gin.(*Context).Next
-	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
-github.com/go-nunu/nunu-layout-advanced/internal/middleware.NoAuth.func1
-	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:56
-github.com/gin-gonic/gin.(*Context).Next
-	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
-github.com/go-nunu/nunu-layout-advanced/internal/middleware.ResponseLogMiddleware.func1
-	/Users/chris/Projects/stu/nunu-layout/internal/middleware/log.go:48
-github.com/gin-gonic/gin.(*Context).Next
-	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
-github.com/go-nunu/nunu-layout-advanced/internal/middleware.NoAuth.func1
-	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:56
-github.com/gin-gonic/gin.(*Context).Next
-	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
-github.com/go-nunu/nunu-layout-advanced/internal/middleware.CORSMiddleware.func1
-	/Users/chris/Projects/stu/nunu-layout/internal/middleware/cors.go:20
-github.com/gin-gonic/gin.(*Context).Next
-	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
-github.com/go-nunu/nunu-layout-advanced/internal/middleware.RequestLogMiddleware.func1
-	/Users/chris/Projects/stu/nunu-layout/internal/middleware/log.go:40
-github.com/gin-gonic/gin.(*Context).Next
-	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
-github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1
-	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/recovery.go:102
-github.com/gin-gonic/gin.(*Context).Next
-	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
-github.com/gin-gonic/gin.LoggerWithConfig.func1
-	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/logger.go:240
-github.com/gin-gonic/gin.(*Context).Next
-	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
-github.com/gin-gonic/gin.(*Engine).handleHTTPRequest
-	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/gin.go:620
-github.com/gin-gonic/gin.(*Engine).ServeHTTP
-	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/gin.go:576
-github.com/go-nunu/nunu-layout-advanced/test/server/handler.NewRequest
-	/Users/chris/Projects/stu/nunu-layout/test/server/handler/user_test.go:58
-github.com/go-nunu/nunu-layout-advanced/test/server/handler.TestCreateUser
-	/Users/chris/Projects/stu/nunu-layout/test/server/handler/user_test.go:84
-testing.tRunner
-	/usr/local/go/src/testing/testing.go:1576
-2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/internal/middleware/log.go:57	响应返回	{"trace": "66ab47224d8602f41e275df08e55582f", "request_method": "POST", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"]}", "request_url": "/user", "request_params": "{\"email\":\"5303221@gmail.com\",\"username\":\"test\"}", "response_body": "{\"code\":1,\"message\":\"token signature is invalid: signature is invalid\",\"data\":{}}", "time": "0ms"}

+ 9 - 8
test/server/handler/user_test.go

@@ -12,13 +12,10 @@ import (
 	"net/http"
 	"net/http/httptest"
 	"os"
+	"strings"
 	"testing"
 )
 
-var jsonHeaders = map[string]string{
-	"Content-Type":  "application/json",
-	"Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM",
-}
 var headers = map[string]string{
 	"Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM",
 }
@@ -54,6 +51,10 @@ func NewRequest(method, path string, header map[string]string, body io.Reader) (
 	for k, v := range header {
 		req.Header.Set(k, v)
 	}
+	if strings.ToUpper(method) != "GET" && body != nil {
+		req.Header.Set("Content-Type", "application/json")
+
+	}
 	w := httptest.NewRecorder()
 	app.ServeHTTP(w, req)
 	response := new(Response)
@@ -64,14 +65,14 @@ func NewRequest(method, path string, header map[string]string, body io.Reader) (
 	return response, nil
 }
 
-func TestGetUserByEmail(t *testing.T) {
+func TestGetUserById(t *testing.T) {
 	response, err := NewRequest("GET",
-		fmt.Sprintf("/user?email=%s", "5303221@gmail.com"),
-		jsonHeaders,
+		fmt.Sprintf("/user?id=%s", "-1"),
+		headers,
 		nil,
 	)
 
-	t.Log("响应结果")
+	t.Log("response")
 	assert.Nil(t, err)
 	assert.Equal(t, 1, response.Code)
 }