mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-07 15:20:25 +08:00
增加全局访问日志
This commit is contained in:
127
internal/web/actions/default/servers/logs/index.go
Normal file
127
internal/web/actions/default/servers/logs/index.go
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package logs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/lists"
|
||||||
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IndexAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) Init() {
|
||||||
|
this.Nav("", "", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) RunGet(params struct {
|
||||||
|
Day string
|
||||||
|
Keyword string
|
||||||
|
Ip string
|
||||||
|
Domain string
|
||||||
|
HasError int
|
||||||
|
|
||||||
|
RequestId string
|
||||||
|
ServerId int64
|
||||||
|
}) {
|
||||||
|
if len(params.Day) == 0 {
|
||||||
|
params.Day = timeutil.Format("Y-m-d")
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Data["serverId"] = 0
|
||||||
|
this.Data["path"] = this.Request.URL.Path
|
||||||
|
this.Data["day"] = params.Day
|
||||||
|
this.Data["keyword"] = params.Keyword
|
||||||
|
this.Data["ip"] = params.Ip
|
||||||
|
this.Data["domain"] = params.Domain
|
||||||
|
this.Data["accessLogs"] = []interface{}{}
|
||||||
|
this.Data["hasError"] = params.HasError
|
||||||
|
|
||||||
|
day := params.Day
|
||||||
|
ipList := []string{}
|
||||||
|
|
||||||
|
if len(day) > 0 && regexp.MustCompile(`\d{4}-\d{2}-\d{2}`).MatchString(day) {
|
||||||
|
day = strings.ReplaceAll(day, "-", "")
|
||||||
|
size := int64(10)
|
||||||
|
|
||||||
|
this.Data["hasError"] = params.HasError
|
||||||
|
|
||||||
|
resp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||||
|
RequestId: params.RequestId,
|
||||||
|
ServerId: params.ServerId,
|
||||||
|
HasError: params.HasError > 0,
|
||||||
|
Day: day,
|
||||||
|
Keyword: params.Keyword,
|
||||||
|
Ip: params.Ip,
|
||||||
|
Domain: params.Domain,
|
||||||
|
Size: size,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(resp.HttpAccessLogs) == 0 {
|
||||||
|
this.Data["accessLogs"] = []interface{}{}
|
||||||
|
} else {
|
||||||
|
this.Data["accessLogs"] = resp.HttpAccessLogs
|
||||||
|
for _, accessLog := range resp.HttpAccessLogs {
|
||||||
|
if len(accessLog.RemoteAddr) > 0 {
|
||||||
|
if !lists.ContainsString(ipList, accessLog.RemoteAddr) {
|
||||||
|
ipList = append(ipList, accessLog.RemoteAddr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.Data["hasMore"] = resp.HasMore
|
||||||
|
this.Data["nextRequestId"] = resp.RequestId
|
||||||
|
|
||||||
|
// 上一个requestId
|
||||||
|
this.Data["hasPrev"] = false
|
||||||
|
this.Data["lastRequestId"] = ""
|
||||||
|
if len(params.RequestId) > 0 {
|
||||||
|
this.Data["hasPrev"] = true
|
||||||
|
prevResp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||||
|
RequestId: params.RequestId,
|
||||||
|
ServerId: params.ServerId,
|
||||||
|
HasError: params.HasError > 0,
|
||||||
|
Day: day,
|
||||||
|
Keyword: params.Keyword,
|
||||||
|
Ip: params.Ip,
|
||||||
|
Domain: params.Domain,
|
||||||
|
Size: size,
|
||||||
|
Reverse: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if int64(len(prevResp.HttpAccessLogs)) == size {
|
||||||
|
this.Data["lastRequestId"] = prevResp.RequestId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据IP查询区域
|
||||||
|
regionMap := map[string]string{} // ip => region
|
||||||
|
if len(ipList) > 0 {
|
||||||
|
resp, err := this.RPC().IPLibraryRPC().LookupIPRegions(this.AdminContext(), &pb.LookupIPRegionsRequest{IpList: ipList})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if resp.IpRegionMap != nil {
|
||||||
|
for ip, region := range resp.IpRegionMap {
|
||||||
|
regionMap[ip] = region.Summary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.Data["regions"] = regionMap
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
21
internal/web/actions/default/servers/logs/init.go
Normal file
21
internal/web/actions/default/servers/logs/init.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package logs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||||
|
"github.com/iwind/TeaGo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||||
|
server.
|
||||||
|
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
|
||||||
|
Data("teaMenu", "servers").
|
||||||
|
Data("teaSubMenu", "log").
|
||||||
|
Prefix("/servers/logs").
|
||||||
|
Get("", new(IndexAction)).
|
||||||
|
EndAll()
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -180,6 +180,11 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map {
|
|||||||
"subtitle": "服务列表",
|
"subtitle": "服务列表",
|
||||||
"icon": "clone outsize",
|
"icon": "clone outsize",
|
||||||
"subItems": []maps.Map{
|
"subItems": []maps.Map{
|
||||||
|
{
|
||||||
|
"name": "访问日志",
|
||||||
|
"url": "/servers/logs",
|
||||||
|
"code": "log",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "通用设置",
|
"name": "通用设置",
|
||||||
"url": "/servers/components",
|
"url": "/servers/components",
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ import (
|
|||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/groups"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/groups"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/log"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/log"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/waf"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/waf"
|
||||||
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/logs"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/metrics"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/metrics"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/metrics/charts"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/metrics/charts"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server"
|
||||||
|
|||||||
33
web/views/@default/servers/logs/index.html
Normal file
33
web/views/@default/servers/logs/index.html
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{$layout}
|
||||||
|
{$template "/datepicker"}
|
||||||
|
|
||||||
|
<first-menu>
|
||||||
|
<menu-item :href="path + '?serverId=' + serverId + '&day=' + day + '&keyword=' + keyword + '&ip=' + ip + '&domain=' + domain" :active="hasError == 0">所有日志</menu-item>
|
||||||
|
<menu-item :href="path + '?serverId=' + serverId + '&day=' + day + '&hasError=1' + '&keyword=' + keyword + '&ip=' + ip + '&domain=' + domain" :active="hasError > 0">错误日志</menu-item>
|
||||||
|
</first-menu>
|
||||||
|
|
||||||
|
<form method="get" class="ui form small" :action="path" autocomplete="off">
|
||||||
|
<input type="hidden" name="serverId" :value="serverId"/>
|
||||||
|
<http-access-log-search-box :v-ip="ip" :v-domain="domain" :v-keyword="keyword">
|
||||||
|
<div class="ui field">
|
||||||
|
<input type="text" name="day" maxlength="10" placeholder="选择日期" style="width:7.8em" id="day-input" v-model="day"/>
|
||||||
|
</div>
|
||||||
|
</http-access-log-search-box>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<p class="comment" v-if="accessLogs.length == 0">暂时还没有访问日志。</p>
|
||||||
|
|
||||||
|
<table class="ui table selectable" v-if="accessLogs.length > 0">
|
||||||
|
<!-- 这里之所以需要添加 :key,是因为要不然不会刷新显示 -->
|
||||||
|
<tr v-for="accessLog in accessLogs" :key="accessLog.requestId">
|
||||||
|
<td><http-access-log-box :v-access-log="accessLog" :v-keyword="keyword"></http-access-log-box></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div v-if="accessLogs.length > 0">
|
||||||
|
<a :href="path + '?serverId=' + serverId + '&requestId=' + lastRequestId + '&day=' + day + '&hasError=' + hasError + '&keyword=' + keyword + '&ip=' + ip + '&domain=' + domain" v-if="hasPrev">上一页</a>
|
||||||
|
<span v-else class="disabled">上一页</span>
|
||||||
|
<span class="disabled"> | </span>
|
||||||
|
<a :href="path + '?serverId=' + serverId + '&requestId=' + nextRequestId + '&day=' + day + '&hasError=' + hasError + '&keyword=' + keyword + '&ip=' + ip + '&domain=' + domain" v-if="hasMore">下一页</a>
|
||||||
|
<span v-else class="disabled">下一页</span>
|
||||||
|
</div>
|
||||||
17
web/views/@default/servers/logs/index.js
Normal file
17
web/views/@default/servers/logs/index.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
this.$delay(function () {
|
||||||
|
let that = this
|
||||||
|
teaweb.datepicker("day-input", function (day) {
|
||||||
|
that.day = day
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
let that = this
|
||||||
|
this.accessLogs.forEach(function (accessLog) {
|
||||||
|
if (typeof (that.regions[accessLog.remoteAddr]) == "string") {
|
||||||
|
accessLog.region = that.regions[accessLog.remoteAddr]
|
||||||
|
} else {
|
||||||
|
accessLog.region = ""
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user