mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 13:10:26 +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": "服务列表",
 | 
			
		||||
			"icon":     "clone outsize",
 | 
			
		||||
			"subItems": []maps.Map{
 | 
			
		||||
				{
 | 
			
		||||
					"name": "访问日志",
 | 
			
		||||
					"url":  "/servers/logs",
 | 
			
		||||
					"code": "log",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					"name": "通用设置",
 | 
			
		||||
					"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/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"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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