Finish the dashboard summary things.
This commit is contained in:
parent
439d23df2d
commit
2d1a95594f
@ -46,17 +46,17 @@ func (this *Context) Init() {
|
|||||||
this.Router = NewRouter()
|
this.Router = NewRouter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (this *Context) OpenDb() {
|
func (this *Context) OpenDb() {
|
||||||
|
|
||||||
var err error = nil
|
var err error = nil
|
||||||
this.DB, err = gorm.Open("mysql", CONFIG.MysqlUrl)
|
this.DB, err = gorm.Open("mysql", CONFIG.MysqlUrl)
|
||||||
|
|
||||||
//是否打开sql日志
|
|
||||||
this.DB.LogMode(false)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("failed to connect mysql database")
|
LOGGER.Panic("failed to connect mysql database")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//是否打开sql日志(在调试阶段可以打开,以方便查看执行的SQL)
|
||||||
|
this.DB.LogMode(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Context) CloseDb() {
|
func (this *Context) CloseDb() {
|
||||||
@ -91,8 +91,7 @@ func (this *Context) registerBean(bean IBean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
err := fmt.Sprintf("注册的【%s】不是Bean类型。", typeName)
|
LOGGER.Panic("注册的【%s】不是Bean类型。", typeName)
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -154,8 +153,8 @@ func (this *Context) GetBean(bean IBean) IBean {
|
|||||||
if val, ok := this.BeanMap[typeName]; ok {
|
if val, ok := this.BeanMap[typeName]; ok {
|
||||||
return val
|
return val
|
||||||
} else {
|
} else {
|
||||||
err := fmt.Sprintf("【%s】没有注册。", typeName)
|
LOGGER.Panic("【%s】没有注册。", typeName)
|
||||||
panic(err)
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,6 @@ func (this *DashboardController) RegisterRoutes() map[string]func(writer http.Re
|
|||||||
//过去七天分时调用量
|
//过去七天分时调用量
|
||||||
func (this *DashboardController) InvokeList(writer http.ResponseWriter, request *http.Request) *WebResult {
|
func (this *DashboardController) InvokeList(writer http.ResponseWriter, request *http.Request) *WebResult {
|
||||||
|
|
||||||
return this.Success(this.dashboardDao.InvokeList())
|
return this.Success("")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package rest
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
|
"github.com/nu7hatch/gouuid"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -9,47 +10,46 @@ type DashboardDao struct {
|
|||||||
BaseDao
|
BaseDao
|
||||||
}
|
}
|
||||||
|
|
||||||
//过去七天调用量
|
//创建
|
||||||
func (this *DashboardDao) InvokeList() []*DashboardInvoke {
|
func (this *DashboardDao) Create(dashboard *Dashboard) *Dashboard {
|
||||||
|
|
||||||
//过去几天
|
timeUUID, _ := uuid.NewV4()
|
||||||
var dayNum = 15;
|
dashboard.Uuid = string(timeUUID.String())
|
||||||
var tableName = Footprint{}.TableName()
|
dashboard.CreateTime = time.Now()
|
||||||
now := time.Now()
|
dashboard.UpdateTime = time.Now()
|
||||||
startDate := now.AddDate(0, 0, 1-dayNum)
|
db := CONTEXT.DB.Create(dashboard)
|
||||||
rows, err := CONTEXT.DB.Raw("SELECT COUNT(uuid) AS invoke_num,COUNT(DISTINCT(ip)) AS uv,dt FROM "+tableName+" WHERE dt>= ? AND dt <= ? GROUP BY dt",
|
this.PanicError(db.Error)
|
||||||
ConvertTimeToDateString(startDate),
|
|
||||||
ConvertTimeToDateString(now)).Rows()
|
|
||||||
this.PanicError(err)
|
|
||||||
defer rows.Close()
|
|
||||||
|
|
||||||
var invokeMap = make(map[string]*DashboardInvoke)
|
return dashboard
|
||||||
var dashboardInvokes []*DashboardInvoke
|
|
||||||
for rows.Next() {
|
|
||||||
var invokeNum int64 = 0;
|
|
||||||
var uv int64 = 0;
|
|
||||||
var dt string;
|
|
||||||
rows.Scan(&invokeNum, &uv, &dt)
|
|
||||||
invokeMap[dt] = &DashboardInvoke{
|
|
||||||
InvokeNum: invokeNum,
|
|
||||||
Uv: uv,
|
|
||||||
Dt: dt,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i := 1 - dayNum; i <= 0; i++ {
|
|
||||||
date := now.AddDate(0, 0, i)
|
|
||||||
dt := ConvertTimeToDateString(date)
|
|
||||||
v, ok := invokeMap[dt]
|
|
||||||
if ok {
|
|
||||||
dashboardInvokes = append(dashboardInvokes, v)
|
|
||||||
} else {
|
|
||||||
dashboardInvokes = append(dashboardInvokes, &DashboardInvoke{
|
|
||||||
InvokeNum: 0,
|
|
||||||
Uv: 0,
|
|
||||||
Dt: dt,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dashboardInvokes
|
//修改一条记录
|
||||||
|
func (this *DashboardDao) Save(dashboard *Dashboard) *Dashboard {
|
||||||
|
|
||||||
|
dashboard.UpdateTime = time.Now()
|
||||||
|
db := CONTEXT.DB.Save(dashboard)
|
||||||
|
this.PanicError(db.Error)
|
||||||
|
|
||||||
|
return dashboard
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//删除一条记录
|
||||||
|
func (this *DashboardDao) Delete(dashboard *Dashboard) {
|
||||||
|
|
||||||
|
db := CONTEXT.DB.Delete(&dashboard)
|
||||||
|
this.PanicError(db.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//按照dt查询
|
||||||
|
func (this *DashboardDao) FindByDt(dt string) *Dashboard {
|
||||||
|
|
||||||
|
// Read
|
||||||
|
var dashboard Dashboard
|
||||||
|
db := CONTEXT.DB.Where(&Dashboard{Dt: dt}).First(&dashboard)
|
||||||
|
if db.Error != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &dashboard
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@ package rest
|
|||||||
*/
|
*/
|
||||||
type Dashboard struct {
|
type Dashboard struct {
|
||||||
Base
|
Base
|
||||||
VisitNum int64 `json:"visitNum"`
|
InvokeNum int64 `json:"invokeNum"`
|
||||||
TotalVisitNum int64 `json:"totalVisitNum"`
|
TotalInvokeNum int64 `json:"totalInvokeNum"`
|
||||||
Uv int64 `json:"uv"`
|
Uv int64 `json:"uv"`
|
||||||
TotalUv int64 `json:"totalUv"`
|
TotalUv int64 `json:"totalUv"`
|
||||||
MatterNum int64 `json:"matterNum"`
|
MatterNum int64 `json:"matterNum"`
|
||||||
|
@ -1,13 +1,21 @@
|
|||||||
package rest
|
package rest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
//@Service
|
//@Service
|
||||||
type DashboardService struct {
|
type DashboardService struct {
|
||||||
Bean
|
Bean
|
||||||
dashboardDao *DashboardDao
|
dashboardDao *DashboardDao
|
||||||
|
footprintDao *FootprintDao
|
||||||
|
matterDao *MatterDao
|
||||||
|
imageCacheDao *ImageCacheDao
|
||||||
userDao *UserDao
|
userDao *UserDao
|
||||||
|
//每天凌晨定时整理器
|
||||||
|
maintainTimer *time.Timer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//初始化方法
|
//初始化方法
|
||||||
func (this *DashboardService) Init() {
|
func (this *DashboardService) Init() {
|
||||||
this.Bean.Init()
|
this.Bean.Init()
|
||||||
@ -18,9 +26,103 @@ func (this *DashboardService) Init() {
|
|||||||
this.dashboardDao = b
|
this.dashboardDao = b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b = CONTEXT.GetBean(this.footprintDao)
|
||||||
|
if b, ok := b.(*FootprintDao); ok {
|
||||||
|
this.footprintDao = b
|
||||||
|
}
|
||||||
|
|
||||||
|
b = CONTEXT.GetBean(this.matterDao)
|
||||||
|
if b, ok := b.(*MatterDao); ok {
|
||||||
|
this.matterDao = b
|
||||||
|
}
|
||||||
|
|
||||||
|
b = CONTEXT.GetBean(this.imageCacheDao)
|
||||||
|
if b, ok := b.(*ImageCacheDao); ok {
|
||||||
|
this.imageCacheDao = b
|
||||||
|
}
|
||||||
|
|
||||||
b = CONTEXT.GetBean(this.userDao)
|
b = CONTEXT.GetBean(this.userDao)
|
||||||
if b, ok := b.(*UserDao); ok {
|
if b, ok := b.(*UserDao); ok {
|
||||||
this.userDao = b
|
this.userDao = b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//立即执行数据清洗任务
|
||||||
|
go this.maintain()
|
||||||
|
}
|
||||||
|
|
||||||
|
//每日清洗离线数据表。
|
||||||
|
func (this *DashboardService) maintain() {
|
||||||
|
|
||||||
|
//准备好下次维护日志的时间。
|
||||||
|
now := time.Now()
|
||||||
|
nextTime := FirstMinuteOfDay(Tomorrow())
|
||||||
|
duration := nextTime.Sub(now)
|
||||||
|
this.logger.Info("每日数据汇总,下次时间:%s ", ConvertTimeToDateTimeString(nextTime))
|
||||||
|
this.maintainTimer = time.AfterFunc(duration, func() {
|
||||||
|
go this.maintain()
|
||||||
|
})
|
||||||
|
|
||||||
|
//准备日期开始结尾
|
||||||
|
startTime := FirstSecondOfDay(Yesterday())
|
||||||
|
endTime := LastSecondOfDay(Yesterday())
|
||||||
|
dt := ConvertTimeToDateString(startTime)
|
||||||
|
longTimeAgo := time.Now()
|
||||||
|
longTimeAgo = longTimeAgo.AddDate(-20, 0, 0)
|
||||||
|
|
||||||
|
this.logger.Info("统计汇总表 %s -> %s", ConvertTimeToDateTimeString(startTime), ConvertTimeToDateTimeString(endTime))
|
||||||
|
|
||||||
|
//判断昨天的记录是否已经生成,如果生成了就直接删除掉
|
||||||
|
dbDashboard := this.dashboardDao.FindByDt(dt)
|
||||||
|
if dbDashboard != nil {
|
||||||
|
this.logger.Info(" %s 的汇总已经存在了,删除以进行更新", dt)
|
||||||
|
this.dashboardDao.Delete(dbDashboard)
|
||||||
|
}
|
||||||
|
|
||||||
|
invokeNum := this.footprintDao.CountBetweenTime(startTime, endTime)
|
||||||
|
this.logger.Info("调用数:%d", invokeNum)
|
||||||
|
|
||||||
|
totalInvokeNum := this.footprintDao.CountBetweenTime(longTimeAgo, endTime)
|
||||||
|
this.logger.Info("历史总调用数:%d", totalInvokeNum)
|
||||||
|
|
||||||
|
uv := this.footprintDao.UvBetweenTime(startTime, endTime)
|
||||||
|
this.logger.Info("UV:%d", uv)
|
||||||
|
|
||||||
|
totalUv := this.footprintDao.UvBetweenTime(longTimeAgo, endTime)
|
||||||
|
this.logger.Info("历史总UV:%d", totalUv)
|
||||||
|
|
||||||
|
matterNum := this.matterDao.CountBetweenTime(startTime, endTime)
|
||||||
|
this.logger.Info("文件数量数:%d", matterNum)
|
||||||
|
|
||||||
|
totalMatterNum := this.matterDao.CountBetweenTime(longTimeAgo, endTime)
|
||||||
|
this.logger.Info("历史文件总数:%d", totalMatterNum)
|
||||||
|
|
||||||
|
matterSize := this.matterDao.SizeBetweenTime(startTime, endTime)
|
||||||
|
this.logger.Info("文件大小:%d", matterSize)
|
||||||
|
|
||||||
|
totalMatterSize := this.matterDao.SizeBetweenTime(longTimeAgo, endTime)
|
||||||
|
this.logger.Info("历史文件总大小:%d", totalMatterSize)
|
||||||
|
|
||||||
|
cacheSize := this.imageCacheDao.SizeBetweenTime(startTime, endTime)
|
||||||
|
this.logger.Info("缓存大小:%d", cacheSize)
|
||||||
|
|
||||||
|
totalCacheSize := this.imageCacheDao.SizeBetweenTime(longTimeAgo, endTime)
|
||||||
|
this.logger.Info("历史缓存总大小:%d", totalCacheSize)
|
||||||
|
|
||||||
|
avgCost := this.footprintDao.AvgCostBetweenTime(startTime, endTime)
|
||||||
|
this.logger.Info("平均耗时:%d ms", avgCost)
|
||||||
|
|
||||||
|
dashboard := &Dashboard{
|
||||||
|
InvokeNum: invokeNum,
|
||||||
|
TotalInvokeNum: totalInvokeNum,
|
||||||
|
Uv: uv,
|
||||||
|
TotalUv: totalUv,
|
||||||
|
MatterNum: matterNum,
|
||||||
|
TotalMatterNum: totalMatterNum,
|
||||||
|
FileSize: matterSize + cacheSize,
|
||||||
|
TotalFileSize: totalMatterSize + totalCacheSize,
|
||||||
|
AvgCost: avgCost,
|
||||||
|
Dt: dt,
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dashboardDao.Create(dashboard)
|
||||||
}
|
}
|
||||||
|
@ -88,3 +88,31 @@ func (this *FootprintDao) Delete(footprint *Footprint) {
|
|||||||
db := CONTEXT.DB.Delete(&footprint)
|
db := CONTEXT.DB.Delete(&footprint)
|
||||||
this.PanicError(db.Error)
|
this.PanicError(db.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取一段时间中,总的数量
|
||||||
|
func (this *FootprintDao) CountBetweenTime(startTime time.Time, endTime time.Time) int64 {
|
||||||
|
var count int64
|
||||||
|
db := CONTEXT.DB.Model(&Footprint{}).Where("create_time >= ? AND create_time <= ?", startTime, endTime).Count(&count)
|
||||||
|
this.PanicError(db.Error)
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取一段时间中UV的数量
|
||||||
|
func (this *FootprintDao) UvBetweenTime(startTime time.Time, endTime time.Time) int64 {
|
||||||
|
var count int64
|
||||||
|
db := CONTEXT.DB.Model(&Footprint{}).Where("create_time >= ? AND create_time <= ?", startTime, endTime).Select("COUNT(DISTINCT(ip))")
|
||||||
|
this.PanicError(db.Error)
|
||||||
|
row := db.Row()
|
||||||
|
row.Scan(&count)
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取一段时间中平均耗时
|
||||||
|
func (this *FootprintDao) AvgCostBetweenTime(startTime time.Time, endTime time.Time) int64 {
|
||||||
|
var cost float64
|
||||||
|
db := CONTEXT.DB.Model(&Footprint{}).Where("create_time >= ? AND create_time <= ?", startTime, endTime).Select("AVG(cost)")
|
||||||
|
this.PanicError(db.Error)
|
||||||
|
row := db.Row()
|
||||||
|
row.Scan(&cost)
|
||||||
|
return int64(cost)
|
||||||
|
}
|
||||||
|
@ -12,7 +12,6 @@ type Footprint struct {
|
|||||||
Params string `json:"params"`
|
Params string `json:"params"`
|
||||||
Cost int64 `json:"cost"`
|
Cost int64 `json:"cost"`
|
||||||
Success bool `json:"success"`
|
Success bool `json:"success"`
|
||||||
Dt string `json:"dt"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set File's table name to be `profiles`
|
// set File's table name to be `profiles`
|
||||||
|
@ -76,7 +76,6 @@ func (this *FootprintService) Trace(writer http.ResponseWriter, request *http.Re
|
|||||||
Params: paramsString,
|
Params: paramsString,
|
||||||
Cost: int64(duration / time.Millisecond),
|
Cost: int64(duration / time.Millisecond),
|
||||||
Success: success,
|
Success: success,
|
||||||
Dt: ConvertTimeToDateString(time.Now()),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
footprint = this.footprintDao.Create(footprint)
|
footprint = this.footprintDao.Create(footprint)
|
||||||
|
@ -192,3 +192,13 @@ func (this *ImageCacheDao) DeleteByMatterUuid(matterUuid string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取一段时间中文件总大小
|
||||||
|
func (this *ImageCacheDao) SizeBetweenTime(startTime time.Time, endTime time.Time) int64 {
|
||||||
|
var size int64
|
||||||
|
db := CONTEXT.DB.Model(&ImageCache{}).Where("create_time >= ? AND create_time <= ?", startTime, endTime).Select("SUM(size)")
|
||||||
|
this.PanicError(db.Error)
|
||||||
|
row := db.Row()
|
||||||
|
row.Scan(&size)
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
@ -32,10 +32,13 @@ func (this *Logger) log(prefix string, format string, v ...interface{}) {
|
|||||||
defer this.Unlock()
|
defer this.Unlock()
|
||||||
|
|
||||||
//控制台中打印日志
|
//控制台中打印日志
|
||||||
fmt.Printf(format+"\r\n", v...)
|
var consoleFormat = fmt.Sprintf("%s%s %s\r\n", prefix, ConvertTimeToTimeString(time.Now()), format)
|
||||||
|
fmt.Printf(consoleFormat, v...)
|
||||||
|
|
||||||
this.goLogger.SetPrefix(prefix)
|
this.goLogger.SetPrefix(prefix)
|
||||||
this.goLogger.Printf(format, v...)
|
//每一行我们加上换行符
|
||||||
|
var fileFormat = fmt.Sprintf("%s\r\n", format)
|
||||||
|
this.goLogger.Printf(fileFormat, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
//处理日志的统一方法。
|
//处理日志的统一方法。
|
||||||
@ -133,7 +136,6 @@ func (this *Logger) closeFile() {
|
|||||||
panic("尝试关闭日志时出错: " + err.Error())
|
panic("尝试关闭日志时出错: " + err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Logger) Destroy() {
|
func (this *Logger) Destroy() {
|
||||||
|
@ -264,3 +264,21 @@ func (this *MatterDao) Delete(matter *Matter) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取一段时间中,总的数量
|
||||||
|
func (this *MatterDao) CountBetweenTime(startTime time.Time, endTime time.Time) int64 {
|
||||||
|
var count int64
|
||||||
|
db := CONTEXT.DB.Model(&Matter{}).Where("create_time >= ? AND create_time <= ?", startTime, endTime).Count(&count)
|
||||||
|
this.PanicError(db.Error)
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取一段时间中文件总大小
|
||||||
|
func (this *MatterDao) SizeBetweenTime(startTime time.Time, endTime time.Time) int64 {
|
||||||
|
var size int64
|
||||||
|
db := CONTEXT.DB.Model(&Matter{}).Where("create_time >= ? AND create_time <= ?", startTime, endTime).Select("SUM(size)")
|
||||||
|
this.PanicError(db.Error)
|
||||||
|
row := db.Row()
|
||||||
|
row.Scan(&size)
|
||||||
|
return size
|
||||||
|
}
|
@ -20,6 +20,11 @@ func ConvertTimeToDateTimeString(time time.Time) string {
|
|||||||
return time.Local().Format("2006-01-02 15:04:05")
|
return time.Local().Format("2006-01-02 15:04:05")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//将一个时间字符串转换成日期时间对象(yyyy-MM-dd HH:mm:ss)
|
||||||
|
func ConvertTimeToTimeString(time time.Time) string {
|
||||||
|
return time.Local().Format("15:04:05")
|
||||||
|
}
|
||||||
|
|
||||||
//将一个时间字符串转换成日期对象(yyyy-MM-dd)
|
//将一个时间字符串转换成日期对象(yyyy-MM-dd)
|
||||||
func ConvertTimeToDateString(time time.Time) string {
|
func ConvertTimeToDateString(time time.Time) string {
|
||||||
return time.Local().Format("2006-01-02")
|
return time.Local().Format("2006-01-02")
|
||||||
@ -37,6 +42,12 @@ func FirstSecondOfDay(day time.Time) time.Time {
|
|||||||
return time.Date(day.Year(), day.Month(), day.Day(), 0, 0, 0, 0, local)
|
return time.Date(day.Year(), day.Month(), day.Day(), 0, 0, 0, 0, local)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//一天中的第一分钟
|
||||||
|
func FirstMinuteOfDay(day time.Time) time.Time {
|
||||||
|
local, _ := time.LoadLocation("Local")
|
||||||
|
return time.Date(day.Year(), day.Month(), day.Day(), 0, 1, 0, 0, local)
|
||||||
|
}
|
||||||
|
|
||||||
//明天此刻的时间
|
//明天此刻的时间
|
||||||
func Tomorrow() time.Time {
|
func Tomorrow() time.Time {
|
||||||
tomorrow := time.Now()
|
tomorrow := time.Now()
|
||||||
|
Loading…
Reference in New Issue
Block a user