diff --git a/internal/web/actions/default/servers/logs/index.go b/internal/web/actions/default/servers/logs/index.go new file mode 100644 index 00000000..653be14d --- /dev/null +++ b/internal/web/actions/default/servers/logs/index.go @@ -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() +} diff --git a/internal/web/actions/default/servers/logs/init.go b/internal/web/actions/default/servers/logs/init.go new file mode 100644 index 00000000..f6f40c24 --- /dev/null +++ b/internal/web/actions/default/servers/logs/init.go @@ -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() + }) +} diff --git a/internal/web/helpers/user_must_auth.go b/internal/web/helpers/user_must_auth.go index c10acc6d..38ae75b8 100644 --- a/internal/web/helpers/user_must_auth.go +++ b/internal/web/helpers/user_must_auth.go @@ -180,6 +180,11 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map { "subtitle": "服务列表", "icon": "clone outsize", "subItems": []maps.Map{ + { + "name": "访问日志", + "url": "/servers/logs", + "code": "log", + }, { "name": "通用设置", "url": "/servers/components", diff --git a/internal/web/import.go b/internal/web/import.go index 2582995b..6a4797b8 100644 --- a/internal/web/import.go +++ b/internal/web/import.go @@ -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/log" _ "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/charts" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server" diff --git a/web/views/@default/servers/logs/index.html b/web/views/@default/servers/logs/index.html new file mode 100644 index 00000000..1023c377 --- /dev/null +++ b/web/views/@default/servers/logs/index.html @@ -0,0 +1,33 @@ +{$layout} +{$template "/datepicker"} + + + 所有日志 + 错误日志 + + +
+ + +
+ +
+
+
+ +

暂时还没有访问日志。

+ + + + + + +
+ +
+ 上一页 + 上一页 +   |   + 下一页 + 下一页 +
\ No newline at end of file diff --git a/web/views/@default/servers/logs/index.js b/web/views/@default/servers/logs/index.js new file mode 100644 index 00000000..e0493fd8 --- /dev/null +++ b/web/views/@default/servers/logs/index.js @@ -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 = "" + } + }) +}) \ No newline at end of file