diff --git a/rest/context.go b/rest/context.go index b2ae8a3..f51bb16 100644 --- a/rest/context.go +++ b/rest/context.go @@ -104,6 +104,11 @@ func (this *Context) registerBeans() { this.registerBean(new(AlienController)) this.registerBean(new(AlienService)) + //dashboard + this.registerBean(new(DashboardController)) + this.registerBean(new(DashboardDao)) + this.registerBean(new(DashboardService)) + //downloadToken this.registerBean(new(DownloadTokenDao)) diff --git a/rest/dashboard_controller.go b/rest/dashboard_controller.go new file mode 100644 index 0000000..956f1af --- /dev/null +++ b/rest/dashboard_controller.go @@ -0,0 +1,46 @@ +package rest + +import ( + "net/http" +) + +type DashboardController struct { + BaseController + dashboardDao *DashboardDao + dashboardService *DashboardService +} + +//初始化方法 +func (this *DashboardController) Init() { + this.BaseController.Init() + + //手动装填本实例的Bean. 这里必须要用中间变量方可。 + b := CONTEXT.GetBean(this.dashboardDao) + if b, ok := b.(*DashboardDao); ok { + this.dashboardDao = b + } + + b = CONTEXT.GetBean(this.dashboardService) + if b, ok := b.(*DashboardService); ok { + this.dashboardService = b + } + +} + +//注册自己的路由。 +func (this *DashboardController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) { + + routeMap := make(map[string]func(writer http.ResponseWriter, request *http.Request)) + + //每个Controller需要主动注册自己的路由。 + routeMap["/api/dashboard/invoke/list"] = this.Wrap(this.InvokeList, USER_ROLE_ADMINISTRATOR) + + return routeMap +} + +//过去七天分时调用量 +func (this *DashboardController) InvokeList(writer http.ResponseWriter, request *http.Request) *WebResult { + + return this.Success(this.dashboardDao.InvokeList()) + +} diff --git a/rest/dashboard_dao.go b/rest/dashboard_dao.go new file mode 100644 index 0000000..b1f88a1 --- /dev/null +++ b/rest/dashboard_dao.go @@ -0,0 +1,48 @@ +package rest + +import ( + _ "github.com/jinzhu/gorm/dialects/mysql" + "time" +) + +type DashboardDao struct { + BaseDao +} + +//过去七天调用量 +func (this *DashboardDao) InvokeList() []*DashboardInvoke { + + var tableName = Footprint{}.TableName() + now := time.Now() + startDate := now.AddDate(0, 0, -6) + rows, err := CONTEXT.DB.Raw("SELECT count(uuid) as invoke_num,dt FROM "+tableName+" where dt>= ? and dt <= ? group by dt", + ConvertTimeToDateString(startDate), + ConvertTimeToDateString(now)).Rows() + this.PanicError(err) + defer rows.Close() + + var invokeMap = make(map[string]int64) + var dashboardInvokes []*DashboardInvoke + for rows.Next() { + var invokeNum int64 = 0; + var dt string; + rows.Scan(&invokeNum, &dt) + invokeMap[dt] = invokeNum + } + for i := -6; i <= 0; i++ { + date := now.AddDate(0, 0, i) + dt := ConvertTimeToDateString(date) + var invokeNum int64 = 0 + v, ok := invokeMap[dt] + if ok { + invokeNum = v + } + + dashboardInvokes = append(dashboardInvokes, &DashboardInvoke{ + InvokeNum: invokeNum, + Dt: dt, + }) + } + + return dashboardInvokes +} diff --git a/rest/dashboard_model.go b/rest/dashboard_model.go new file mode 100644 index 0000000..974121e --- /dev/null +++ b/rest/dashboard_model.go @@ -0,0 +1,9 @@ +package rest + +/** + * 总调用量 + */ +type DashboardInvoke struct { + InvokeNum int64 `json:"invokeNum"` + Dt string `json:"dt"` +} diff --git a/rest/dashboard_service.go b/rest/dashboard_service.go new file mode 100644 index 0000000..c738935 --- /dev/null +++ b/rest/dashboard_service.go @@ -0,0 +1,26 @@ +package rest + +//@Service +type DashboardService struct { + Bean + dashboardDao *DashboardDao + userDao *UserDao +} + + +//初始化方法 +func (this *DashboardService) Init() { + this.Bean.Init() + + //手动装填本实例的Bean. 这里必须要用中间变量方可。 + b := CONTEXT.GetBean(this.dashboardDao) + if b, ok := b.(*DashboardDao); ok { + this.dashboardDao = b + } + + b = CONTEXT.GetBean(this.userDao) + if b, ok := b.(*UserDao); ok { + this.userDao = b + } + +} diff --git a/rest/footprint_model.go b/rest/footprint_model.go index 337d413..b857e6c 100644 --- a/rest/footprint_model.go +++ b/rest/footprint_model.go @@ -5,13 +5,14 @@ package rest */ type Footprint struct { Base - UserUuid string `json:"userUuid"` - Ip string `json:"ip"` - Host string `json:"host"` - Uri string `json:"uri"` - Params string `json:"params"` - Cost int64 `json:"cost"` - Success bool `json:"success"` + UserUuid string `json:"userUuid"` + Ip string `json:"ip"` + Host string `json:"host"` + Uri string `json:"uri"` + Params string `json:"params"` + Cost int64 `json:"cost"` + Success bool `json:"success"` + Dt string `json:"dt"` } // set File's table name to be `profiles` diff --git a/rest/footprint_service.go b/rest/footprint_service.go index f406dd8..244ce2c 100644 --- a/rest/footprint_service.go +++ b/rest/footprint_service.go @@ -76,6 +76,7 @@ func (this *FootprintService) Trace(writer http.ResponseWriter, request *http.Re Params: paramsString, Cost: int64(duration / time.Millisecond), Success: success, + Dt: ConvertTimeToDateString(time.Now()), } footprint = this.footprintDao.Create(footprint) diff --git a/rest/logger.go b/rest/logger.go index dc02da1..03f2fb2 100644 --- a/rest/logger.go +++ b/rest/logger.go @@ -10,7 +10,7 @@ import ( //日志系统必须高保 //全局唯一的日志对象(在main函数中初始化) -var LOGGER *Logger = &Logger{} +var LOGGER = &Logger{} //在Logger的基础上包装一个全新的Logger. type Logger struct { diff --git a/rest/util_cache.go b/rest/util_cache.go index 0457d6c..61bba35 100644 --- a/rest/util_cache.go +++ b/rest/util_cache.go @@ -3,7 +3,6 @@ package rest import ( "errors" "fmt" - "log" "sort" "sync" "time" @@ -102,8 +101,6 @@ type CacheTable struct { cleanupTimer *time.Timer // 缓存清理周期 cleanupInterval time.Duration - // 该缓存表的日志 - logger *log.Logger // 获取一个不存在的缓存项时的回调函数 loadData func(key interface{}, args ...interface{}) *CacheItem // 向缓存表增加缓存项时的回调函数 @@ -150,13 +147,6 @@ func (table *CacheTable) SetDeleteCallback(f func(*CacheItem)) { table.deleteCallback = f } -// 设置缓存表需要使用的log -func (table *CacheTable) SetLogger(logger *log.Logger) { - table.Lock() - defer table.Unlock() - table.logger = logger -} - //终结检查,被自调整的时间触发 func (table *CacheTable) checkExpire() { table.Lock() @@ -164,7 +154,7 @@ func (table *CacheTable) checkExpire() { table.cleanupTimer.Stop() } if table.cleanupInterval > 0 { - table.log("Expiration check triggered after", table.cleanupInterval, "for table") + table.log("Expiration check triggered after %v for table", table.cleanupInterval) } else { table.log("Expiration check installed for table") } @@ -191,7 +181,7 @@ func (table *CacheTable) checkExpire() { //缓存项已经过期 _, e := table.Delete(key) if e != nil { - table.log("删除缓存项时出错 ", e.Error()) + table.log("删除缓存项时出错 %v", e.Error()) } } else { //查找最靠近结束生命周期的项目 @@ -218,7 +208,7 @@ func (table *CacheTable) Add(key interface{}, duration time.Duration, data inter // 将缓存项放入表中 table.Lock() - table.log("Adding item with key", key, "and lifespan of", duration, "to table") + table.log("Adding item with key %v and lifespan of %v to table", key, duration) table.items[key] = item // 取出需要的东西,释放锁 @@ -265,7 +255,7 @@ func (table *CacheTable) Delete(key interface{}) (*CacheItem, error) { table.Lock() defer table.Unlock() - table.log("Deleting item with key", key, "created on", r.createTime, "and hit", r.count, "times from table") + table.log("Deleting item with key %v created on %v and hit %v times from table", key, r.createTime, r.count) delete(table.items, key) return r, nil @@ -290,7 +280,7 @@ func (table *CacheTable) NotFoundAdd(key interface{}, lifeSpan time.Duration, da } item := NewCacheItem(key, lifeSpan, data) - table.log("Adding item with key", key, "and lifespan of", lifeSpan, "to table") + table.log("Adding item with key %v and lifespan of %v to table", key, lifeSpan) table.items[key] = item // 取出需要的内容,释放锁 @@ -339,11 +329,11 @@ func (table *CacheTable) Value(key interface{}, args ...interface{}) (*CacheItem } // 删除缓存表中的所有项目 -func (table *CacheTable) Flush() { +func (table *CacheTable) Truncate() { table.Lock() defer table.Unlock() - table.log("Flushing table") + table.log("Truncate table") table.items = make(map[interface{}]*CacheItem) table.cleanupInterval = 0 @@ -395,13 +385,8 @@ func (table *CacheTable) MostAccessed(count int64) []*CacheItem { } // 打印日志 -func (table *CacheTable) log(v ...interface{}) { - if table.logger == nil { - fmt.Println(v...) - return - } - - table.logger.Println(v...) +func (table *CacheTable) log(format string, v ...interface{}) { + LOGGER.Info(format, v...) } //新建一个缓存Table diff --git a/rest/util_time.go b/rest/util_time.go index f55d659..38772c8 100644 --- a/rest/util_time.go +++ b/rest/util_time.go @@ -6,7 +6,7 @@ import ( ) //将一个时间字符串转换成时间对象(yyyy-MM-dd HH:mm:ss) -func ConvertToTime(timeString string) time.Time { +func ConvertDateTimeStringToTime(timeString string) time.Time { local, _ := time.LoadLocation("Local") t, err := time.ParseInLocation("2006-01-02 15:04:05", timeString, local) if err != nil { @@ -15,6 +15,16 @@ func ConvertToTime(timeString string) time.Time { return t } +//将一个时间字符串转换成日期时间对象(yyyy-MM-dd HH:mm:ss) +func ConvertTimeToDateTimeString(time time.Time) string { + return time.Local().Format("2006-01-02 15:04:05") +} + +//将一个时间字符串转换成日期对象(yyyy-MM-dd) +func ConvertTimeToDateString(time time.Time) string { + return time.Local().Format("2006-01-02") +} + //一天中的最后一秒钟 func LastSecondOfDay(day time.Time) time.Time { local, _ := time.LoadLocation("Local")