提交 4bd9307e 编写于 作者: G Granty1

Adjust log module

上级 b75d8391
......@@ -3,20 +3,24 @@ package cmd
import (
"fmt"
"gin-vue-admin/config"
"gin-vue-admin/init/log"
"github.com/gin-gonic/gin"
"net/http"
"time"
)
func RunWindowsServer(Router *gin.Engine) {
func RunWindowsServer(Router *gin.Engine, logger log.Logger) {
address := fmt.Sprintf(":%d", config.GinVueAdminconfig.System.Addr)
s := &http.Server{
Addr: fmt.Sprintf(":%d", config.GinVueAdminconfig.System.Addr),
Addr: address,
Handler: Router,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
time.Sleep(10 * time.Microsecond)
logger.Debug("server run success on ", address)
fmt.Printf(`欢迎使用 Gin-Vue-Admin
作者:奇淼 And Spike666
微信:shouzi_1994
......
......@@ -14,6 +14,7 @@ type Config struct {
System System `json:"system"`
JWT JWT `json:"jwt"`
Captcha Captcha `json:"captcha"`
Log Log `json:"log"`
}
type System struct { // 系统配置
......@@ -54,6 +55,27 @@ type Captcha struct { // 验证码配置
ImgHeight int `json:"imgHeight"`
}
/**
Log Config
"CRITICAL"
"ERROR"
"WARNING"
"NOTICE"
"INFO"
"DEBUG"
*/
type Log struct {
// log 打印的前缀
Prefix string `json:"prefix"`
// 是否显示打印log的文件具体路径
LogFile bool `json:"logFile"`
// 在控制台打印log的级别, []默认不打印
Stdout []string `json:"stdout"`
// 在文件中打印log的级别 []默认不打印
File []string `json:"file"`
}
var GinVueAdminconfig Config
var VTool *viper.Viper
......@@ -68,7 +90,7 @@ func init() {
}
v.WatchConfig()
v.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config file changed:", e.Name)
fmt.Println("config file changed:", e.Name)
if err := v.Unmarshal(&GinVueAdminconfig); err != nil {
fmt.Println(err)
}
......
......@@ -3,30 +3,48 @@ module gin-vue-admin
go 1.12
require (
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
github.com/casbin/casbin v1.9.1
github.com/casbin/gorm-adapter v1.0.0
github.com/dchest/captcha v0.0.0-20170622155422-6a29415a8364
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
github.com/fsnotify/fsnotify v1.4.7
github.com/gin-gonic/gin v1.4.0
github.com/go-redis/redis v6.15.6+incompatible
github.com/fsnotify/fsnotify v1.4.9
github.com/gin-gonic/gin v1.6.1
github.com/go-openapi/spec v0.19.7 // indirect
github.com/go-openapi/swag v0.19.8 // indirect
github.com/go-redis/redis v6.15.7+incompatible
github.com/go-sql-driver/mysql v1.5.0 // indirect
github.com/golang/protobuf v1.3.5 // indirect
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
github.com/jinzhu/gorm v1.9.10
github.com/jinzhu/gorm v1.9.12
github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 // indirect
github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f
github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect
github.com/pkg/errors v0.8.1
github.com/lib/pq v1.3.0 // indirect
github.com/mailru/easyjson v0.7.1 // indirect
github.com/mitchellh/mapstructure v1.2.2 // indirect
github.com/onsi/ginkgo v1.7.0 // indirect
github.com/onsi/gomega v1.4.3 // indirect
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
github.com/pelletier/go-toml v1.6.0 // indirect
github.com/pkg/errors v0.9.1
github.com/qiniu/api.v7 v7.2.5+incompatible
github.com/qiniu/x v7.0.8+incompatible // indirect
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
github.com/satori/go.uuid v1.2.0
github.com/sirupsen/logrus v1.2.0
github.com/spf13/viper v1.4.0
github.com/spf13/afero v1.2.2 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.6.2
github.com/swaggo/gin-swagger v1.2.0
github.com/swaggo/swag v1.5.1
github.com/swaggo/swag v1.6.5
github.com/tebeka/strftime v0.1.3 // indirect
github.com/unrolled/secure v1.0.6
github.com/unrolled/secure v1.0.7
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 // indirect
golang.org/x/net v0.0.0-20200320220750-118fecf932d8 // indirect
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd // indirect
golang.org/x/tools v0.0.0-20200324003944-a576cf524670 // indirect
gopkg.in/ini.v1 v1.55.0 // indirect
qiniupkg.com/x v7.0.8+incompatible // indirect
)
package initRedis
import (
"fmt"
"gin-vue-admin/config"
"gin-vue-admin/init/log"
"github.com/go-redis/redis"
)
var DEFAULTREDIS *redis.Client
func InitRedis() (client *redis.Client) {
func InitRedis(logger log.Logger) (client *redis.Client) {
client = redis.NewClient(&redis.Options{
Addr: config.GinVueAdminconfig.RedisAdmin.Addr,
Password: config.GinVueAdminconfig.RedisAdmin.Password, // no password set
......@@ -16,9 +16,9 @@ func InitRedis() (client *redis.Client) {
})
pong, err := client.Ping().Result()
if err != nil {
fmt.Println(pong, err)
logger.Error(err)
} else {
fmt.Println(pong, err)
logger.Info("redis connect ping response:", pong)
DEFAULTREDIS = client
}
return client
......
......@@ -2,6 +2,7 @@ package initRouter
import (
_ "gin-vue-admin/docs"
"gin-vue-admin/init/log"
"gin-vue-admin/middleware"
"gin-vue-admin/router"
"github.com/gin-gonic/gin"
......@@ -10,14 +11,20 @@ import (
)
//初始化总路由
func InitRouter() *gin.Engine {
func InitRouter(logger log.Logger) *gin.Engine {
var Router = gin.Default()
//Router.Use(middleware.LoadTls()) // 打开就能玩https了
Router.Use(middleware.Logger()) // 如果不需要日志 请关闭这里
Router.Use(middleware.Cors()) // 跨域
// 如果不需要日志 请关闭这里
Router.Use(middleware.LoggerMiddlewareFactory(logger))
logger.Debug("use middleware logger")
// 跨域
Router.Use(middleware.CorsMiddlewareFactory())
logger.Debug("use middleware cors")
Router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
ApiGroup := Router.Group("") // 方便统一添加路由组前缀 多服务器上线使用
//Router.Use(middleware.Logger())
logger.Debug("register swagger handler")
// 方便统一添加路由组前缀 多服务器上线使用
ApiGroup := Router.Group("")
router.InitUserRouter(ApiGroup) // 注册用户路由
router.InitBaseRouter(ApiGroup) // 注册基础功能路由 不做鉴权
router.InitMenuRouter(ApiGroup) // 注册menu路由
......@@ -29,5 +36,6 @@ func InitRouter() *gin.Engine {
router.InitJwtRouter(ApiGroup) // jwt相关路由
router.InitSystemRouter(ApiGroup) // system相关路由
router.InitCustomerRouter(ApiGroup) // 客户路由
logger.Info("router register success")
return Router
}
package qmlog
// 日志初始化包 调用qmlog.QMLog.Info 记录日志 24小时切割 日志保存7天 可自行设置
import (
"fmt"
"gin-vue-admin/tools"
rotatelogs "github.com/lestrrat/go-file-rotatelogs"
"github.com/rifflock/lfshook"
"github.com/sirupsen/logrus"
"os"
"time"
)
var QMLog = logrus.New()
//禁止logrus的输出
func InitLog() *logrus.Logger {
src, err := os.OpenFile(os.DevNull, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
fmt.Println("err", err)
}
QMLog.Out = src
QMLog.SetLevel(logrus.DebugLevel)
if ok, _ := tools.PathExists("./log"); !ok {
// Directory not exist
fmt.Println("Create log.")
_ = os.Mkdir("log", os.ModePerm)
}
apiLogPath := "./log/api.log"
logWriter, err := rotatelogs.New(
apiLogPath+".%Y-%m-%d-%H-%M.log",
rotatelogs.WithLinkName(apiLogPath), // 生成软链,指向最新日志文件
rotatelogs.WithMaxAge(7*24*time.Hour), // 文件最大保存时间
rotatelogs.WithRotationTime(24*time.Hour), // 日志切割时间间隔
)
writeMap := lfshook.WriterMap{
logrus.InfoLevel: logWriter,
logrus.FatalLevel: logWriter,
}
lfHook := lfshook.NewHook(writeMap, &logrus.JSONFormatter{})
QMLog.AddHook(lfHook)
return QMLog
}
......@@ -2,17 +2,17 @@ package qmsql
import (
"gin-vue-admin/config"
"gin-vue-admin/init/log"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"log"
)
var DEFAULTDB *gorm.DB
//初始化数据库并产生数据库全局变量
func InitMysql(admin config.MysqlAdmin) *gorm.DB {
func InitMysql(admin config.MysqlAdmin, logger log.Logger) *gorm.DB {
if db, err := gorm.Open("mysql", admin.Username+":"+admin.Password+"@("+admin.Path+")/"+admin.Dbname+"?"+admin.Config); err != nil {
log.Printf("DEFAULTDB数据库启动异常%S", err)
logger.Error("DEFAULTDB数据库启动异常",err)
} else {
DEFAULTDB = db
DEFAULTDB.DB().SetMaxIdleConns(10)
......
package registTable
import (
"gin-vue-admin/init/log"
"gin-vue-admin/model/dbModel"
"gin-vue-admin/model/sysModel"
"github.com/jinzhu/gorm"
)
//注册数据库表专用
func RegistTable(db *gorm.DB) {
func RegistTable(db *gorm.DB, logger log.Logger) {
db.AutoMigrate(sysModel.SysUser{},
sysModel.SysAuthority{},
sysModel.SysMenu{},
......@@ -21,4 +22,5 @@ func RegistTable(db *gorm.DB) {
dbModel.ExaFileChunk{},
dbModel.ExaCustomer{},
)
logger.Debug("register table success")
}
package main
import (
"fmt"
"gin-vue-admin/cmd"
"gin-vue-admin/config"
"gin-vue-admin/init/initRedis"
"gin-vue-admin/init/initRouter"
"gin-vue-admin/init/qmlog"
"gin-vue-admin/init/log/qmlog"
"gin-vue-admin/init/qmsql"
"gin-vue-admin/init/registTable"
//"runtime"
......@@ -20,15 +21,23 @@ import (
// @BasePath /
func main() {
qmlog.InitLog() // 初始化日志
db := qmsql.InitMysql(config.GinVueAdminconfig.MysqlAdmin) // 链接初始化数据库
var err error
logger, err := qmlog.NewLogger()
if err != nil {
fmt.Println(err)
}
// 链接初始化数据库
db := qmsql.InitMysql(config.GinVueAdminconfig.MysqlAdmin, logger)
if config.GinVueAdminconfig.System.UseMultipoint {
_ = initRedis.InitRedis() // 初始化redis服务
// 初始化redis服务
_ = initRedis.InitRedis(logger)
}
registTable.RegistTable(db) // 注册数据库表
defer qmsql.DEFAULTDB.Close() // 程序结束前关闭数据库链接
Router := initRouter.InitRouter() // 注册路由
qmlog.QMLog.Info("服务器开启") // 日志测试代码
// 注册数据库表
registTable.RegistTable(db, logger)
// 程序结束前关闭数据库链接
defer qmsql.DEFAULTDB.Close()
// 注册路由
Router := initRouter.InitRouter(logger)
//Router.RunTLS(":443","ssl.pem", "ssl.key") // https支持 需要添加中间件
//sysType := runtime.GOOS
//
......@@ -38,6 +47,6 @@ func main() {
//}
//if sysType == "windows" {
// WIN系统
cmd.RunWindowsServer(Router)
cmd.RunWindowsServer(Router, logger)
//}
}
......@@ -6,7 +6,7 @@ import (
)
// 处理跨域请求,支持options访问
func Cors() gin.HandlerFunc {
func CorsMiddlewareFactory() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
c.Header("Access-Control-Allow-Origin", "*")
......
......@@ -2,7 +2,7 @@ package middleware
import (
"bytes"
"gin-vue-admin/init/qmlog"
"gin-vue-admin/init/log"
"net/http/httputil"
"strings"
"time"
......@@ -10,8 +10,7 @@ import (
"github.com/gin-gonic/gin"
)
func Logger() gin.HandlerFunc {
log := qmlog.QMLog
func LoggerMiddlewareFactory(logger log.Logger) gin.HandlerFunc {
return func(c *gin.Context) {
// request time
start := time.Now()
......@@ -28,8 +27,8 @@ func Logger() gin.HandlerFunc {
// copy request content
req, _ := httputil.DumpRequest(c.Request, true)
if logFlag {
log.Infof(`| %s | %s | %s | %5s | %s\n`,
`Request :`, method, clientIP, path, string(req))
logger.Debug(
"Request:", method, clientIP, path, string(req))
}
// replace writer
cusWriter := &responseBodyWriter{
......@@ -45,8 +44,8 @@ func Logger() gin.HandlerFunc {
latency := end.Sub(start)
statusCode := c.Writer.Status()
if logFlag {
log.Infof(`| %s | %3d | %13v | %s \n`,
`Response:`,
logger.Debug(
"Response:",
statusCode,
latency,
cusWriter.body.String())
......
......@@ -7,7 +7,7 @@
},
"mysqladmin": {
"username": "root",
"password": "Aa@6447985",
"password": "YINGL19980716.",
"path": "127.0.0.1:3306",
"dbname": "qmPlus",
"config": "charset=utf8\u0026parseTime=True\u0026loc=Local"
......@@ -30,5 +30,11 @@
"keyLong": 6,
"imgWidth": 120,
"imgHeight": 40
},
"log": {
"prefix": "[GIN-VUE-ADMIN]",
"logFile": false,
"stdout": ["DEBUG"],
"file": ["WARNING"]
}
}
\ No newline at end of file
<template>
<div>
<!-- 此版本为简单版 -->
<!-- 结构体基础配置 -->
<el-form ref="form" :model="form" label-width="100px" :inline="true">
<el-form-item label="结构名称" :span="8">
<el-input v-model="form.structName"></el-input>
</el-form-item>
<el-form-item label="结构类型" :span="8">
<el-select v-model="form.structType" multiple placeholder="请选择结构类型(多选)">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-form>
<!-- 组件列表 -->
<div class="button-box clearflex">
<el-button @click="editAndAddComponent()" type="primary">新增组件</el-button>
</div>
<el-table
:data="form.components"
border stripe>
<el-table-column
type="index"
label="序列"
width="180">
</el-table-column>
<el-table-column
prop="componentName"
label="组件名"
width="180">
</el-table-column>
<el-table-column
prop="componentType"
label="组件数据类型"
width="180">
</el-table-column>
<el-table-column
prop="componentShowType"
label="组件展示类型">
</el-table-column>
<el-table-column
prop="dictionaryName"
label="字典名称(选)">
</el-table-column>
<el-table-column
label="操作">
<template slot-scope="scope">
<el-button @click="editAndAddComponent(scope.row)">编辑</el-button>
<el-popover
placement="top"
width="160"
v-model="scope.row.visible">
<p>这是一段内容这是一段内容确定删除吗?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="scope.row.visible = false">取消</el-button>
<el-button type="primary" size="mini" @click="deleteComponent(scope.$index)">确定</el-button>
</div>
<el-button slot="reference">删除</el-button>
</el-popover>
</template>
</el-table-column>
</el-table>
<!-- 组件列表 -->
<div class="button-box clearflex">
<el-button @click="enterForm" type="primary">提交</el-button>
</div>
<!-- 组件弹窗 -->
<el-dialog title="组件内容" :visible.sync="dialogFlag">
<ComponentDialog :dialogMiddle="dialogMiddle" />
<div slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="enterDialog">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
const componentTemplate={
componentName:"",
componentType:"",
componentShowType:"",
dictionaryName:"",
isMultiple:false,
nideDictionary:false,
visible:false,
componentDictionary:[]
}
import ComponentDialog from "@/view/superAdmin/autoCode/component/componentDialog.vue"
export default {
name:"autoCode",
data(){
return{
addFlag:"",
form:{
structName:"",
structType:[],
components:[]
},
options:[
{label:"表格类型",value:"grid"},
{label:"表单类型",value:"form"}
],
dialogMiddle:{},
bk:{},
dialogFlag:false
}
},
components:{
ComponentDialog
},
methods:{
editAndAddComponent(item){
this.dialogFlag = true
if(item){
this.addFlag="edit"
this.bk=JSON.parse(JSON.stringify(item))
this.dialogMiddle = item
}else{
this.addFlag="add"
this.dialogMiddle = JSON.parse(JSON.stringify(componentTemplate))
}
},
enterDialog(){
if(this.addFlag=="add"){
this.form.components.push(this.dialogMiddle)
}
this.dialogFlag = false
},
closeDialog(){
if(this.addFlag=="edit"){
this.dialogMiddle = this.bk
}
this.dialogFlag = false
},
deleteComponent(index){
this.form.components.splice(index,1)
},
enterForm(){
}
}
}
</script>
<style scope lang="scss">
.button-box {
padding: 10px 20px;
.el-button {
float: right;
}
}
</style>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册