mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-12 19:30:26 +08:00
实现基本的访问日志策略
This commit is contained in:
179
internal/web/actions/default/servers/accesslogs/createPopup.go
Normal file
179
internal/web/actions/default/servers/accesslogs/createPopup.go
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package ipbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/iwind/TeaGo/actions"
|
||||||
|
"github.com/iwind/TeaGo/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreatePopupAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreatePopupAction) Init() {
|
||||||
|
this.Nav("", "", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreatePopupAction) RunGet(params struct{}) {
|
||||||
|
this.Data["types"] = serverconfigs.FindAllAccessLogStorageTypes()
|
||||||
|
this.Data["syslogPriorities"] = serverconfigs.AccessLogSyslogStoragePriorities
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CreatePopupAction) RunPost(params struct {
|
||||||
|
Name string
|
||||||
|
Type string
|
||||||
|
|
||||||
|
// file
|
||||||
|
FilePath string
|
||||||
|
FileAutoCreate bool
|
||||||
|
|
||||||
|
// es
|
||||||
|
EsEndpoint string
|
||||||
|
EsIndex string
|
||||||
|
EsMappingType string
|
||||||
|
EsUsername string
|
||||||
|
EsPassword string
|
||||||
|
|
||||||
|
// mysql
|
||||||
|
MysqlHost string
|
||||||
|
MysqlPort int
|
||||||
|
MysqlUsername string
|
||||||
|
MysqlPassword string
|
||||||
|
MysqlDatabase string
|
||||||
|
MysqlTable string
|
||||||
|
MysqlLogField string
|
||||||
|
|
||||||
|
// tcp
|
||||||
|
TcpNetwork string
|
||||||
|
TcpAddr string
|
||||||
|
|
||||||
|
// syslog
|
||||||
|
SyslogProtocol string
|
||||||
|
SyslogServerAddr string
|
||||||
|
SyslogServerPort int
|
||||||
|
SyslogSocket string
|
||||||
|
SyslogTag string
|
||||||
|
SyslogPriority int
|
||||||
|
|
||||||
|
// command
|
||||||
|
CommandCommand string
|
||||||
|
CommandArgs string
|
||||||
|
CommandDir string
|
||||||
|
|
||||||
|
IsPublic bool
|
||||||
|
|
||||||
|
Must *actions.Must
|
||||||
|
CSRF *actionutils.CSRF
|
||||||
|
}) {
|
||||||
|
var policyId int64 = 0
|
||||||
|
defer func() {
|
||||||
|
this.CreateLogInfo("创建访问日志策略 %d", policyId)
|
||||||
|
}()
|
||||||
|
|
||||||
|
params.Must.
|
||||||
|
Field("name", params.Name).
|
||||||
|
Require("请输入日志策略的名称").
|
||||||
|
Field("type", params.Type).
|
||||||
|
Require("请选择存储类型")
|
||||||
|
|
||||||
|
var options interface{} = nil
|
||||||
|
switch params.Type {
|
||||||
|
case serverconfigs.AccessLogStorageTypeFile:
|
||||||
|
params.Must.
|
||||||
|
Field("filePath", params.FilePath).
|
||||||
|
Require("请输入日志文件路径")
|
||||||
|
|
||||||
|
storage := new(serverconfigs.AccessLogFileStorageConfig)
|
||||||
|
storage.Path = params.FilePath
|
||||||
|
storage.AutoCreate = params.FileAutoCreate
|
||||||
|
options = storage
|
||||||
|
case serverconfigs.AccessLogStorageTypeES:
|
||||||
|
params.Must.
|
||||||
|
Field("esEndpoint", params.EsEndpoint).
|
||||||
|
Require("请输入Endpoint").
|
||||||
|
Field("esIndex", params.EsIndex).
|
||||||
|
Require("请输入Index名称").
|
||||||
|
Field("esMappingType", params.EsMappingType).
|
||||||
|
Require("请输入Mapping名称")
|
||||||
|
|
||||||
|
storage := new(serverconfigs.AccessLogESStorageConfig)
|
||||||
|
storage.Endpoint = params.EsEndpoint
|
||||||
|
storage.Index = params.EsIndex
|
||||||
|
storage.MappingType = params.EsMappingType
|
||||||
|
storage.Username = params.EsUsername
|
||||||
|
storage.Password = params.EsPassword
|
||||||
|
options = storage
|
||||||
|
case serverconfigs.AccessLogStorageTypeTCP:
|
||||||
|
params.Must.
|
||||||
|
Field("tcpNetwork", params.TcpNetwork).
|
||||||
|
Require("请选择网络协议").
|
||||||
|
Field("tcpAddr", params.TcpAddr).
|
||||||
|
Require("请输入网络地址")
|
||||||
|
|
||||||
|
storage := new(serverconfigs.AccessLogTCPStorageConfig)
|
||||||
|
storage.Network = params.TcpNetwork
|
||||||
|
storage.Addr = params.TcpAddr
|
||||||
|
options = storage
|
||||||
|
case serverconfigs.AccessLogStorageTypeSyslog:
|
||||||
|
switch params.SyslogProtocol {
|
||||||
|
case serverconfigs.AccessLogSyslogStorageProtocolTCP, serverconfigs.AccessLogSyslogStorageProtocolUDP:
|
||||||
|
params.Must.
|
||||||
|
Field("syslogServerAddr", params.SyslogServerAddr).
|
||||||
|
Require("请输入网络地址")
|
||||||
|
case serverconfigs.AccessLogSyslogStorageProtocolSocket:
|
||||||
|
params.Must.
|
||||||
|
Field("syslogSocket", params.SyslogSocket).
|
||||||
|
Require("请输入Socket路径")
|
||||||
|
}
|
||||||
|
|
||||||
|
storage := new(serverconfigs.AccessLogSyslogStorageConfig)
|
||||||
|
storage.Protocol = params.SyslogProtocol
|
||||||
|
storage.ServerAddr = params.SyslogServerAddr
|
||||||
|
storage.ServerPort = params.SyslogServerPort
|
||||||
|
storage.Socket = params.SyslogSocket
|
||||||
|
storage.Tag = params.SyslogTag
|
||||||
|
storage.Priority = params.SyslogPriority
|
||||||
|
options = storage
|
||||||
|
case serverconfigs.AccessLogStorageTypeCommand:
|
||||||
|
params.Must.
|
||||||
|
Field("commandCommand", params.CommandCommand).
|
||||||
|
Require("请输入可执行命令")
|
||||||
|
|
||||||
|
storage := new(serverconfigs.AccessLogCommandStorageConfig)
|
||||||
|
storage.Command = params.CommandCommand
|
||||||
|
storage.Args = cmd.ParseArgs(params.CommandArgs)
|
||||||
|
storage.Dir = params.CommandDir
|
||||||
|
options = storage
|
||||||
|
}
|
||||||
|
|
||||||
|
if options == nil {
|
||||||
|
this.Fail("找不到选择的存储类型")
|
||||||
|
}
|
||||||
|
|
||||||
|
optionsJSON, err := json.Marshal(options)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
createResp, err := this.RPC().HTTPAccessLogPolicyRPC().CreateHTTPAccessLogPolicy(this.AdminContext(), &pb.CreateHTTPAccessLogPolicyRequest{
|
||||||
|
Name: params.Name,
|
||||||
|
Type: params.Type,
|
||||||
|
OptionsJSON: optionsJSON,
|
||||||
|
CondsJSON: nil, // TODO
|
||||||
|
IsPublic: params.IsPublic,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
policyId = createResp.HttpAccessLogPolicyId
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
26
internal/web/actions/default/servers/accesslogs/delete.go
Normal file
26
internal/web/actions/default/servers/accesslogs/delete.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package ipbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeleteAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *DeleteAction) RunPost(params struct {
|
||||||
|
PolicyId int64
|
||||||
|
}) {
|
||||||
|
defer this.CreateLogInfo("删除访问日志策略 %d", params.PolicyId)
|
||||||
|
|
||||||
|
_, err := this.RPC().HTTPAccessLogPolicyRPC().DeleteHTTPAccessLogPolicy(this.AdminContext(), &pb.DeleteHTTPAccessLogPolicyRequest{HttpAccessLogPolicyId: params.PolicyId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
57
internal/web/actions/default/servers/accesslogs/index.go
Normal file
57
internal/web/actions/default/servers/accesslogs/index.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package ipbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IndexAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) Init() {
|
||||||
|
this.Nav("", "", "index")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) RunGet(params struct{}) {
|
||||||
|
countResp, err := this.RPC().HTTPAccessLogPolicyRPC().CountAllEnabledHTTPAccessLogPolicies(this.AdminContext(), &pb.CountAllEnabledHTTPAccessLogPoliciesRequest{})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
page := this.NewPage(countResp.Count)
|
||||||
|
this.Data["page"] = page.AsHTML()
|
||||||
|
|
||||||
|
policiesResp, err := this.RPC().HTTPAccessLogPolicyRPC().ListEnabledHTTPAccessLogPolicies(this.AdminContext(), &pb.ListEnabledHTTPAccessLogPoliciesRequest{
|
||||||
|
Offset: page.Offset,
|
||||||
|
Size: page.Size,
|
||||||
|
})
|
||||||
|
var policyMaps = []maps.Map{}
|
||||||
|
for _, policy := range policiesResp.HttpAccessLogPolicies {
|
||||||
|
var optionsMap = maps.Map{}
|
||||||
|
if len(policy.OptionsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(policy.OptionsJSON, &optionsMap)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
policyMaps = append(policyMaps, maps.Map{
|
||||||
|
"id": policy.Id,
|
||||||
|
"name": policy.Name,
|
||||||
|
"type": policy.Type,
|
||||||
|
"typeName": serverconfigs.FindAccessLogStorageTypeName(policy.Type),
|
||||||
|
"isOn": policy.IsOn,
|
||||||
|
"isPublic": policy.IsPublic,
|
||||||
|
"options": optionsMap,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.Data["policies"] = policyMaps
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
26
internal/web/actions/default/servers/accesslogs/init.go
Normal file
26
internal/web/actions/default/servers/accesslogs/init.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package ipbox
|
||||||
|
|
||||||
|
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)).
|
||||||
|
Prefix("/servers/accesslogs").
|
||||||
|
Data("teaMenu", "servers").
|
||||||
|
Data("teaSubMenu", "accesslog").
|
||||||
|
Get("", new(IndexAction)).
|
||||||
|
GetPost("/createPopup", new(CreatePopupAction)).
|
||||||
|
Get("/policy", new(PolicyAction)).
|
||||||
|
GetPost("/test", new(TestAction)).
|
||||||
|
GetPost("/update", new(UpdateAction)).
|
||||||
|
Post("/delete", new(DeleteAction)).
|
||||||
|
EndAll()
|
||||||
|
})
|
||||||
|
}
|
||||||
36
internal/web/actions/default/servers/accesslogs/policy.go
Normal file
36
internal/web/actions/default/servers/accesslogs/policy.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package ipbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/accesslogs/policyutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PolicyAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *PolicyAction) Init() {
|
||||||
|
this.Nav("", "", "policy")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *PolicyAction) RunGet(params struct {
|
||||||
|
PolicyId int64
|
||||||
|
}) {
|
||||||
|
err := policyutils.InitPolicy(this.Parent(), params.PolicyId)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var policyMap = this.Data.GetMap("policy")
|
||||||
|
if policyMap.GetString("type") == serverconfigs.AccessLogStorageTypeSyslog {
|
||||||
|
this.Data["syslogPriorityName"] = serverconfigs.FindAccessLogSyslogStoragePriorityName(policyMap.GetMap("options").GetInt("priority"))
|
||||||
|
} else {
|
||||||
|
this.Data["syslogPriorityName"] = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package policyutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InitPolicy 初始化访问日志策略
|
||||||
|
func InitPolicy(parent *actionutils.ParentAction, policyId int64) error {
|
||||||
|
rpcClient, err := rpc.SharedRPC()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
policyResp, err := rpcClient.HTTPAccessLogPolicyRPC().FindEnabledHTTPAccessLogPolicy(parent.AdminContext(), &pb.FindEnabledHTTPAccessLogPolicyRequest{HttpAccessLogPolicyId: policyId})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var policy = policyResp.HttpAccessLogPolicy
|
||||||
|
if policy == nil {
|
||||||
|
return errors.New("can not find policy '" + types.String(policyId) + "'")
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = maps.Map{}
|
||||||
|
if len(policy.OptionsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(policy.OptionsJSON, &options)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.Data["policy"] = maps.Map{
|
||||||
|
"id": policy.Id,
|
||||||
|
"name": policy.Name,
|
||||||
|
"type": policy.Type,
|
||||||
|
"typeName": serverconfigs.FindAccessLogStorageTypeName(policy.Type),
|
||||||
|
"isOn": policy.IsOn,
|
||||||
|
"isPublic": policy.IsPublic,
|
||||||
|
"options": options,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
57
internal/web/actions/default/servers/accesslogs/test.go
Normal file
57
internal/web/actions/default/servers/accesslogs/test.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package ipbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/accesslogs/policyutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/actions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *TestAction) Init() {
|
||||||
|
this.Nav("", "", "test")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *TestAction) RunGet(params struct {
|
||||||
|
PolicyId int64
|
||||||
|
}) {
|
||||||
|
err := policyutils.InitPolicy(this.Parent(), params.PolicyId)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *TestAction) RunPost(params struct {
|
||||||
|
PolicyId int64
|
||||||
|
BodyJSON []byte
|
||||||
|
|
||||||
|
Must *actions.Must
|
||||||
|
}) {
|
||||||
|
defer this.CreateLogInfo("测试向访问日志策略 %d 写入数据", params.PolicyId)
|
||||||
|
|
||||||
|
var accessLog = &pb.HTTPAccessLog{}
|
||||||
|
err := json.Unmarshal(params.BodyJSON, accessLog)
|
||||||
|
if err != nil {
|
||||||
|
this.Fail("发送内容不是有效的JSON:" + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = this.RPC().HTTPAccessLogPolicyRPC().WriteHTTPAccessLogPolicy(this.AdminContext(), &pb.WriteHTTPAccessLogPolicyRequest{
|
||||||
|
HttpAccessLogPolicyId: params.PolicyId,
|
||||||
|
HttpAccessLog: accessLog,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.Fail("发送失败:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
195
internal/web/actions/default/servers/accesslogs/update.go
Normal file
195
internal/web/actions/default/servers/accesslogs/update.go
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package ipbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/accesslogs/policyutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/iwind/TeaGo/actions"
|
||||||
|
"github.com/iwind/TeaGo/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdateAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UpdateAction) Init() {
|
||||||
|
this.Nav("", "", "update")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UpdateAction) RunGet(params struct {
|
||||||
|
PolicyId int64
|
||||||
|
}) {
|
||||||
|
err := policyutils.InitPolicy(this.Parent(), params.PolicyId)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Data["types"] = serverconfigs.FindAllAccessLogStorageTypes()
|
||||||
|
this.Data["syslogPriorities"] = serverconfigs.AccessLogSyslogStoragePriorities
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UpdateAction) RunPost(params struct {
|
||||||
|
PolicyId int64
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// file
|
||||||
|
FilePath string
|
||||||
|
FileAutoCreate bool
|
||||||
|
|
||||||
|
// es
|
||||||
|
EsEndpoint string
|
||||||
|
EsIndex string
|
||||||
|
EsMappingType string
|
||||||
|
EsUsername string
|
||||||
|
EsPassword string
|
||||||
|
|
||||||
|
// mysql
|
||||||
|
MysqlHost string
|
||||||
|
MysqlPort int
|
||||||
|
MysqlUsername string
|
||||||
|
MysqlPassword string
|
||||||
|
MysqlDatabase string
|
||||||
|
MysqlTable string
|
||||||
|
MysqlLogField string
|
||||||
|
|
||||||
|
// tcp
|
||||||
|
TcpNetwork string
|
||||||
|
TcpAddr string
|
||||||
|
|
||||||
|
// syslog
|
||||||
|
SyslogProtocol string
|
||||||
|
SyslogServerAddr string
|
||||||
|
SyslogServerPort int
|
||||||
|
SyslogSocket string
|
||||||
|
SyslogTag string
|
||||||
|
SyslogPriority int
|
||||||
|
|
||||||
|
// command
|
||||||
|
CommandCommand string
|
||||||
|
CommandArgs string
|
||||||
|
CommandDir string
|
||||||
|
|
||||||
|
IsOn bool
|
||||||
|
IsPublic bool
|
||||||
|
|
||||||
|
Must *actions.Must
|
||||||
|
CSRF *actionutils.CSRF
|
||||||
|
}) {
|
||||||
|
defer this.CreateLogInfo("修改访问日志策略 %d", params.PolicyId)
|
||||||
|
|
||||||
|
policyResp, err := this.RPC().HTTPAccessLogPolicyRPC().FindEnabledHTTPAccessLogPolicy(this.AdminContext(), &pb.FindEnabledHTTPAccessLogPolicyRequest{HttpAccessLogPolicyId: params.PolicyId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var policy = policyResp.HttpAccessLogPolicy
|
||||||
|
if policy == nil {
|
||||||
|
this.Fail("找不到要修改的策略")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
params.Must.
|
||||||
|
Field("name", params.Name).
|
||||||
|
Require("请输入日志策略的名称")
|
||||||
|
|
||||||
|
var options interface{} = nil
|
||||||
|
switch policy.Type {
|
||||||
|
case serverconfigs.AccessLogStorageTypeFile:
|
||||||
|
params.Must.
|
||||||
|
Field("filePath", params.FilePath).
|
||||||
|
Require("请输入日志文件路径")
|
||||||
|
|
||||||
|
storage := new(serverconfigs.AccessLogFileStorageConfig)
|
||||||
|
storage.Path = params.FilePath
|
||||||
|
storage.AutoCreate = params.FileAutoCreate
|
||||||
|
options = storage
|
||||||
|
case serverconfigs.AccessLogStorageTypeES:
|
||||||
|
params.Must.
|
||||||
|
Field("esEndpoint", params.EsEndpoint).
|
||||||
|
Require("请输入Endpoint").
|
||||||
|
Field("esIndex", params.EsIndex).
|
||||||
|
Require("请输入Index名称").
|
||||||
|
Field("esMappingType", params.EsMappingType).
|
||||||
|
Require("请输入Mapping名称")
|
||||||
|
|
||||||
|
storage := new(serverconfigs.AccessLogESStorageConfig)
|
||||||
|
storage.Endpoint = params.EsEndpoint
|
||||||
|
storage.Index = params.EsIndex
|
||||||
|
storage.MappingType = params.EsMappingType
|
||||||
|
storage.Username = params.EsUsername
|
||||||
|
storage.Password = params.EsPassword
|
||||||
|
options = storage
|
||||||
|
case serverconfigs.AccessLogStorageTypeTCP:
|
||||||
|
params.Must.
|
||||||
|
Field("tcpNetwork", params.TcpNetwork).
|
||||||
|
Require("请选择网络协议").
|
||||||
|
Field("tcpAddr", params.TcpAddr).
|
||||||
|
Require("请输入网络地址")
|
||||||
|
|
||||||
|
storage := new(serverconfigs.AccessLogTCPStorageConfig)
|
||||||
|
storage.Network = params.TcpNetwork
|
||||||
|
storage.Addr = params.TcpAddr
|
||||||
|
options = storage
|
||||||
|
case serverconfigs.AccessLogStorageTypeSyslog:
|
||||||
|
switch params.SyslogProtocol {
|
||||||
|
case serverconfigs.AccessLogSyslogStorageProtocolTCP, serverconfigs.AccessLogSyslogStorageProtocolUDP:
|
||||||
|
params.Must.
|
||||||
|
Field("syslogServerAddr", params.SyslogServerAddr).
|
||||||
|
Require("请输入网络地址")
|
||||||
|
case serverconfigs.AccessLogSyslogStorageProtocolSocket:
|
||||||
|
params.Must.
|
||||||
|
Field("syslogSocket", params.SyslogSocket).
|
||||||
|
Require("请输入Socket路径")
|
||||||
|
}
|
||||||
|
|
||||||
|
storage := new(serverconfigs.AccessLogSyslogStorageConfig)
|
||||||
|
storage.Protocol = params.SyslogProtocol
|
||||||
|
storage.ServerAddr = params.SyslogServerAddr
|
||||||
|
storage.ServerPort = params.SyslogServerPort
|
||||||
|
storage.Socket = params.SyslogSocket
|
||||||
|
storage.Tag = params.SyslogTag
|
||||||
|
storage.Priority = params.SyslogPriority
|
||||||
|
options = storage
|
||||||
|
case serverconfigs.AccessLogStorageTypeCommand:
|
||||||
|
params.Must.
|
||||||
|
Field("commandCommand", params.CommandCommand).
|
||||||
|
Require("请输入可执行命令")
|
||||||
|
|
||||||
|
storage := new(serverconfigs.AccessLogCommandStorageConfig)
|
||||||
|
storage.Command = params.CommandCommand
|
||||||
|
storage.Args = cmd.ParseArgs(params.CommandArgs)
|
||||||
|
storage.Dir = params.CommandDir
|
||||||
|
options = storage
|
||||||
|
}
|
||||||
|
|
||||||
|
if options == nil {
|
||||||
|
this.Fail("找不到选择的存储类型")
|
||||||
|
}
|
||||||
|
|
||||||
|
optionsJSON, err := json.Marshal(options)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = this.RPC().HTTPAccessLogPolicyRPC().UpdateHTTPAccessLogPolicy(this.AdminContext(), &pb.UpdateHTTPAccessLogPolicyRequest{
|
||||||
|
HttpAccessLogPolicyId: params.PolicyId,
|
||||||
|
Name: params.Name,
|
||||||
|
OptionsJSON: optionsJSON,
|
||||||
|
CondsJSON: nil, // TODO
|
||||||
|
IsOn: params.IsOn,
|
||||||
|
IsPublic: params.IsPublic,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/iwind/TeaGo/actions"
|
"github.com/iwind/TeaGo/actions"
|
||||||
"github.com/iwind/TeaGo/maps"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type IndexAction struct {
|
type IndexAction struct {
|
||||||
@@ -31,22 +30,6 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
this.Data["webId"] = webConfig.Id
|
this.Data["webId"] = webConfig.Id
|
||||||
this.Data["accessLogConfig"] = webConfig.AccessLogRef
|
this.Data["accessLogConfig"] = webConfig.AccessLogRef
|
||||||
|
|
||||||
// 可选的缓存策略
|
|
||||||
policiesResp, err := this.RPC().HTTPAccessLogPolicyRPC().FindAllEnabledHTTPAccessLogPolicies(this.AdminContext(), &pb.FindAllEnabledHTTPAccessLogPoliciesRequest{})
|
|
||||||
if err != nil {
|
|
||||||
this.ErrorPage(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
policyMaps := []maps.Map{}
|
|
||||||
for _, policy := range policiesResp.AccessLogPolicies {
|
|
||||||
policyMaps = append(policyMaps, maps.Map{
|
|
||||||
"id": policy.Id,
|
|
||||||
"name": policy.Name,
|
|
||||||
"isOn": policy.IsOn, // TODO 这里界面上显示是否开启状态
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.Data["accessLogPolicies"] = policyMaps
|
|
||||||
|
|
||||||
// 通用变量
|
// 通用变量
|
||||||
this.Data["fields"] = serverconfigs.HTTPAccessLogFields
|
this.Data["fields"] = serverconfigs.HTTPAccessLogFields
|
||||||
this.Data["defaultFieldCodes"] = serverconfigs.HTTPAccessLogDefaultFieldsCodes
|
this.Data["defaultFieldCodes"] = serverconfigs.HTTPAccessLogDefaultFieldsCodes
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/iwind/TeaGo/actions"
|
"github.com/iwind/TeaGo/actions"
|
||||||
"github.com/iwind/TeaGo/maps"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type IndexAction struct {
|
type IndexAction struct {
|
||||||
@@ -28,22 +27,6 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
this.Data["webId"] = webConfig.Id
|
this.Data["webId"] = webConfig.Id
|
||||||
this.Data["accessLogConfig"] = webConfig.AccessLogRef
|
this.Data["accessLogConfig"] = webConfig.AccessLogRef
|
||||||
|
|
||||||
// 可选的缓存策略
|
|
||||||
policiesResp, err := this.RPC().HTTPAccessLogPolicyRPC().FindAllEnabledHTTPAccessLogPolicies(this.AdminContext(), &pb.FindAllEnabledHTTPAccessLogPoliciesRequest{})
|
|
||||||
if err != nil {
|
|
||||||
this.ErrorPage(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
policyMaps := []maps.Map{}
|
|
||||||
for _, policy := range policiesResp.AccessLogPolicies {
|
|
||||||
policyMaps = append(policyMaps, maps.Map{
|
|
||||||
"id": policy.Id,
|
|
||||||
"name": policy.Name,
|
|
||||||
"isOn": policy.IsOn, // TODO 这里界面上显示是否开启状态
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.Data["accessLogPolicies"] = policyMaps
|
|
||||||
|
|
||||||
// 通用变量
|
// 通用变量
|
||||||
this.Data["fields"] = serverconfigs.HTTPAccessLogFields
|
this.Data["fields"] = serverconfigs.HTTPAccessLogFields
|
||||||
this.Data["defaultFieldCodes"] = serverconfigs.HTTPAccessLogDefaultFieldsCodes
|
this.Data["defaultFieldCodes"] = serverconfigs.HTTPAccessLogDefaultFieldsCodes
|
||||||
|
|||||||
@@ -194,6 +194,12 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map {
|
|||||||
"url": "/servers/components/waf",
|
"url": "/servers/components/waf",
|
||||||
"code": "waf",
|
"code": "waf",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "日志策略",
|
||||||
|
"url": "/servers/accesslogs",
|
||||||
|
"code": "accesslog",
|
||||||
|
"isOn": teaconst.IsPlus,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "IP名单",
|
"name": "IP名单",
|
||||||
"url": "/servers/iplists",
|
"url": "/servers/iplists",
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import (
|
|||||||
|
|
||||||
// 服务相关
|
// 服务相关
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers"
|
||||||
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/accesslogs"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/certs"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/certs"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache"
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
let sourceCodeBoxIndex = 0
|
let sourceCodeBoxIndex = 0
|
||||||
|
|
||||||
Vue.component("source-code-box", {
|
Vue.component("source-code-box", {
|
||||||
props: ["type", "id"],
|
props: ["name", "type", "id", "read-only"],
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
|
let readOnly = this.readOnly
|
||||||
|
if (typeof readOnly != "boolean") {
|
||||||
|
readOnly = true
|
||||||
|
}
|
||||||
|
console.log("readonly:", readOnly) // TODO
|
||||||
let box = document.getElementById("source-code-box-" + this.index)
|
let box = document.getElementById("source-code-box-" + this.index)
|
||||||
let valueBox = document.getElementById(this.valueBoxId)
|
let valueBox = document.getElementById(this.valueBoxId)
|
||||||
let value = ""
|
let value = ""
|
||||||
@@ -15,7 +20,7 @@ Vue.component("source-code-box", {
|
|||||||
theme: "idea",
|
theme: "idea",
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
value: "",
|
value: "",
|
||||||
readOnly: true,
|
readOnly: readOnly,
|
||||||
showCursorWhenSelecting: true,
|
showCursorWhenSelecting: true,
|
||||||
height: "auto",
|
height: "auto",
|
||||||
//scrollbarStyle: null,
|
//scrollbarStyle: null,
|
||||||
@@ -49,6 +54,6 @@ Vue.component("source-code-box", {
|
|||||||
},
|
},
|
||||||
template: `<div class="source-code-box">
|
template: `<div class="source-code-box">
|
||||||
<div style="display: none" :id="valueBoxId"><slot></slot></div>
|
<div style="display: none" :id="valueBoxId"><slot></slot></div>
|
||||||
<textarea :id="'source-code-box-' + index"></textarea>
|
<textarea :id="'source-code-box-' + index" :name="name"></textarea>
|
||||||
</div>`
|
</div>`
|
||||||
})
|
})
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
Vue.component("http-access-log-config-box", {
|
Vue.component("http-access-log-config-box", {
|
||||||
props: ["v-access-log-config", "v-fields", "v-default-field-codes", "v-access-log-policies", "v-is-location"],
|
props: ["v-access-log-config", "v-fields", "v-default-field-codes", "v-is-location"],
|
||||||
data: function () {
|
data: function () {
|
||||||
let that = this
|
let that = this
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
that.changeFields()
|
that.changeFields()
|
||||||
that.changePolicy()
|
|
||||||
}, 100)
|
}, 100)
|
||||||
|
|
||||||
let accessLog = {
|
let accessLog = {
|
||||||
@@ -19,9 +18,6 @@ Vue.component("http-access-log-config-box", {
|
|||||||
status4: true,
|
status4: true,
|
||||||
status5: true,
|
status5: true,
|
||||||
|
|
||||||
storageOnly: false,
|
|
||||||
storagePolicies: [],
|
|
||||||
|
|
||||||
firewallOnly: false
|
firewallOnly: false
|
||||||
}
|
}
|
||||||
if (this.vAccessLogConfig != null) {
|
if (this.vAccessLogConfig != null) {
|
||||||
@@ -35,9 +31,6 @@ Vue.component("http-access-log-config-box", {
|
|||||||
v.isChecked = accessLog.fields.$contains(v.code)
|
v.isChecked = accessLog.fields.$contains(v.code)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.vAccessLogPolicies.forEach(function (v) {
|
|
||||||
v.isChecked = accessLog.storagePolicies.$contains(v.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
accessLog: accessLog
|
accessLog: accessLog
|
||||||
@@ -50,13 +43,6 @@ Vue.component("http-access-log-config-box", {
|
|||||||
}).map(function (v) {
|
}).map(function (v) {
|
||||||
return v.code
|
return v.code
|
||||||
})
|
})
|
||||||
},
|
|
||||||
changePolicy: function () {
|
|
||||||
this.accessLog.storagePolicies = this.vAccessLogPolicies.filter(function (v) {
|
|
||||||
return v.isChecked
|
|
||||||
}).map(function (v) {
|
|
||||||
return v.id
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
template: `<div>
|
template: `<div>
|
||||||
@@ -110,28 +96,6 @@ Vue.component("http-access-log-config-box", {
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-show="vAccessLogPolicies.length > 0">
|
|
||||||
<td>选择输出的日志策略</td>
|
|
||||||
<td>
|
|
||||||
<span class="disabled" v-if="vAccessLogPolicies.length == 0">暂时还没有缓存策略。</span>
|
|
||||||
<div v-if="vAccessLogPolicies.length > 0">
|
|
||||||
<div class="ui checkbox" v-for="policy in vAccessLogPolicies" style="width:10em;margin-bottom:0.8em">
|
|
||||||
<input type="checkbox" v-model="policy.isChecked" @change="changePolicy" />
|
|
||||||
<label>{{policy.name}}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-show="vAccessLogPolicies.length > 0">
|
|
||||||
<td>是否只输出到日志策略</td>
|
|
||||||
<td>
|
|
||||||
<div class="ui checkbox">
|
|
||||||
<input type="checkbox" v-model="accessLog.storageOnly"/>
|
|
||||||
<label></label>
|
|
||||||
</div>
|
|
||||||
<p class="comment">选中表示只输出日志到日志策略,而停止默认的日志存储。</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|||||||
@@ -345,8 +345,9 @@ Vue.component("metric-chart", {
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (this.item.keys != null) {
|
||||||
// IP相关操作
|
// IP相关操作
|
||||||
if (this.item.keys != null && this.item.keys.$contains("${remoteAddr}")) {
|
if (this.item.keys.$contains("${remoteAddr}")) {
|
||||||
let that = this
|
let that = this
|
||||||
chart.on("click", function (args) {
|
chart.on("click", function (args) {
|
||||||
let index = that.item.keys.$indexesOf("${remoteAddr}")[0]
|
let index = that.item.keys.$indexesOf("${remoteAddr}")[0]
|
||||||
@@ -357,6 +358,7 @@ Vue.component("metric-chart", {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
renderTable: function (chart) {
|
renderTable: function (chart) {
|
||||||
let table = `<table class="ui table celled">
|
let table = `<table class="ui table celled">
|
||||||
|
|||||||
6
web/views/@default/servers/accesslogs/@menu.html
Normal file
6
web/views/@default/servers/accesslogs/@menu.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<first-menu>
|
||||||
|
<menu-item code="index" href="/servers/accesslogs">策略列表</menu-item>
|
||||||
|
<menu-item @click.prevent="createPolicy">[创建策略]</menu-item>
|
||||||
|
<span class="item disabled">|</span>
|
||||||
|
<span class="item"><tip-icon content="可以利用日志策略将服务的访问日志输出到特定的媒介中。"></tip-icon></span>
|
||||||
|
</first-menu>
|
||||||
7
web/views/@default/servers/accesslogs/@policy_menu.html
Normal file
7
web/views/@default/servers/accesslogs/@policy_menu.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<first-menu>
|
||||||
|
<menu-item href="/servers/accesslogs">策略列表</menu-item>
|
||||||
|
<span class="item disabled">|</span>
|
||||||
|
<menu-item :href="'policy?policyId=' + policy.id" code="policy">"{{policy.name}}"详情</menu-item>
|
||||||
|
<menu-item :href="'test?policyId=' + policy.id" code="test">测试</menu-item>
|
||||||
|
<menu-item :href="'update?policyId=' + policy.id" code="update">修改</menu-item>
|
||||||
|
</first-menu>
|
||||||
216
web/views/@default/servers/accesslogs/createPopup.html
Normal file
216
web/views/@default/servers/accesslogs/createPopup.html
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
{$layout "layout_popup"}
|
||||||
|
|
||||||
|
<h3>创建策略</h3>
|
||||||
|
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||||
|
<csrf-token></csrf-token>
|
||||||
|
<table class="ui table definition selectable">
|
||||||
|
<tr>
|
||||||
|
<td class="title">策略名称 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="name" maxlength="50" ref="focus"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>存储类型 *</td>
|
||||||
|
<td>
|
||||||
|
<select class="ui dropdown auto-width" name="type" v-model="type">
|
||||||
|
<option value="">[选择类型]</option>
|
||||||
|
<option v-for="type in types" :value="type.code">{{type.name}}</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- 文件 -->
|
||||||
|
<tbody v-show="type == 'file'">
|
||||||
|
<tr>
|
||||||
|
<td>日志文件路径 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="filePath"/>
|
||||||
|
<p class="comment">
|
||||||
|
存储日志的文件路径,文件名中支持变量:
|
||||||
|
<span class="ui label tiny">年:${year}</span>
|
||||||
|
<span class="ui label tiny">月:${month}</span>
|
||||||
|
<span class="ui label tiny">周:${week}</span>
|
||||||
|
<span class="ui label tiny">日:${day}</span>
|
||||||
|
<span class="ui label tiny">时:${hour}</span>
|
||||||
|
<span class="ui label tiny">分:${minute}</span>
|
||||||
|
<span class="ui label tiny">秒:${second}</span>
|
||||||
|
<span class="ui label tiny">年月日:${date}</span>,比如<span class="ui label tiny">/var/log/web-access-${date}.log</span>。
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>是否自动创建目录</td>
|
||||||
|
<td>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input type="checkbox" name="fileAutoCreate" value="1" checked="checked"/>
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
<p class="comment">选中后,如果文件目录不存在时可以自动创建。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- Elastic Search -->
|
||||||
|
<tbody v-show="type == 'es'">
|
||||||
|
<tr>
|
||||||
|
<td>Endpoint *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="esEndpoint"/>
|
||||||
|
<p class="comment">ES HTTP接口地址,类似于192.168.1.100:9200</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Index *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="esIndex"/>
|
||||||
|
<p class="comment">Index名称,支持变量:
|
||||||
|
<span class="ui label tiny">年:${year}</span>
|
||||||
|
<span class="ui label tiny">月:${month}</span>
|
||||||
|
<span class="ui label tiny">周:${week}</span>
|
||||||
|
<span class="ui label tiny">日:${day}</span>
|
||||||
|
<span class="ui label tiny">时:${hour}</span>
|
||||||
|
<span class="ui label tiny">分:${minute}</span>
|
||||||
|
<span class="ui label tiny">秒:${second}</span>
|
||||||
|
<span class="ui label tiny">年月日:${date}</span></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Mapping Type *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="esMappingType"/>
|
||||||
|
<p class="comment">Mapping名称,支持变量:
|
||||||
|
<span class="ui label tiny">年:${year}</span>
|
||||||
|
<span class="ui label tiny">月:${month}</span>
|
||||||
|
<span class="ui label tiny">周:${week}</span>
|
||||||
|
<span class="ui label tiny">日:${day}</span>
|
||||||
|
<span class="ui label tiny">时:${hour}</span>
|
||||||
|
<span class="ui label tiny">分:${minute}</span>
|
||||||
|
<span class="ui label tiny">秒:${second}</span>
|
||||||
|
<span class="ui label tiny">年月日:${date}</span></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>认证用户名</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="esUsername"/>
|
||||||
|
<p class="comment">配置了认证后才需要填写。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>认证密码</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="esPassword"/>
|
||||||
|
<p class="comment">配置了认证后才需要填写。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- TCP Socket -->
|
||||||
|
<tbody v-show="type == 'tcp'">
|
||||||
|
<tr>
|
||||||
|
<td>网络协议 *</td>
|
||||||
|
<td>
|
||||||
|
<select name="tcpNetwork" class="ui dropdown" style="width:10em">
|
||||||
|
<option value="tcp">TCP</option>
|
||||||
|
<option value="unix">Unix Socket</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>网络地址 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="tcpAddr"/>
|
||||||
|
<p class="comment">接收日志的网络地址</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- Syslog -->
|
||||||
|
<tbody v-show="type == 'syslog'">
|
||||||
|
<tr>
|
||||||
|
<td>网络协议</td>
|
||||||
|
<td>
|
||||||
|
<select class="ui dropdown" name="syslogProtocol" v-model="syslogProtocol" style="width:10em">
|
||||||
|
<option value="none">[无]</option>
|
||||||
|
<option value="tcp">TCP</option>
|
||||||
|
<option value="udp">UDP</option>
|
||||||
|
<option value="socket">Unix Socket</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr v-if="syslogProtocol == 'tcp' || syslogProtocol == 'udp'">
|
||||||
|
<td>网络地址 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="syslogServerAddr"/>
|
||||||
|
<p class="comment">IP地址或主机名,不包括端口。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-if="syslogProtocol == 'tcp' || syslogProtocol == 'udp'">
|
||||||
|
<td>端口</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="syslogServerPort"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr v-if="syslogProtocol == 'socket'">
|
||||||
|
<td>Socket路径 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="syslogSocket"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>标签<em>(Tag)</em></td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="syslogTag"/>
|
||||||
|
<p class="comment">选填项。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>优先级<em>(Priority)</em></td>
|
||||||
|
<td>
|
||||||
|
<select class="ui dropdown" name="syslogPriority" style="width:10em">
|
||||||
|
<option v-for="priority in syslogPriorities" :value="priority.value">{{priority.name}}</option>
|
||||||
|
</select>
|
||||||
|
<p class="comment">选填项。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- 命令行输入流 -->
|
||||||
|
<tbody v-show="type == 'command'">
|
||||||
|
<tr>
|
||||||
|
<td>可执行命令 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="commandCommand"/>
|
||||||
|
<p class="comment">不带参数的可执行命令地址</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>参数</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="commandArgs"/>
|
||||||
|
<p class="comment">执行命令需要的参数</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>工作目录</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="commandDir"/>
|
||||||
|
<p class="comment">命令执行所在的工作目录</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>是否公用</td>
|
||||||
|
<td>
|
||||||
|
<checkbox name="isPublic" value="1"></checkbox>
|
||||||
|
<p class="comment">选中后表示自动将此策略应用于所有集群,同时只会有一个公用策略。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<submit-btn></submit-btn>
|
||||||
|
</form>
|
||||||
8
web/views/@default/servers/accesslogs/createPopup.js
Normal file
8
web/views/@default/servers/accesslogs/createPopup.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
this.type = ""
|
||||||
|
|
||||||
|
/**
|
||||||
|
* syslog
|
||||||
|
*/
|
||||||
|
this.syslogProtocol = "none"
|
||||||
|
})
|
||||||
44
web/views/@default/servers/accesslogs/index.html
Normal file
44
web/views/@default/servers/accesslogs/index.html
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{$layout}
|
||||||
|
{$template "menu"}
|
||||||
|
|
||||||
|
<p class="comment" v-if="policies.length == 0">暂时还没有访问日志策略。</p>
|
||||||
|
|
||||||
|
<table class="ui table celled selectable" v-if="policies.length > 0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>策略名称</th>
|
||||||
|
<th class="three op">类型</th>
|
||||||
|
<th>主要参数</th>
|
||||||
|
<th class="two wide">状态</th>
|
||||||
|
<th class="two op">操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr v-for="policy in policies">
|
||||||
|
<td>{{policy.name}}
|
||||||
|
<div style="margin-top: 0.3em" v-if="policy.isPublic">
|
||||||
|
<span class="ui label olive tiny basic">公用</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>{{policy.typeName}}</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="policy.options == null" class="disabled">-</span>
|
||||||
|
<span v-else-if="policy.type == 'es'">Endpoint: {{policy.options.endpoint}}</span>
|
||||||
|
<span v-else-if="policy.type == 'file'">文件路径:{{policy.options.path}}</span>
|
||||||
|
<span v-else-if="policy.type == 'tcp'">网络地址:{{policy.options.addr}}</span>
|
||||||
|
<span v-else-if="policy.type == 'command'">可执行命令:{{policy.options.command}}</span>
|
||||||
|
<span v-else-if="policy.type == 'syslog'">
|
||||||
|
<span v-if="policy.options.protocol == 'tcp'">TCP {{policy.options.serverAddr}}</span>
|
||||||
|
<span v-if="policy.options.protocol == 'udp'">UDP {{policy.options.serverAddr}}</span>
|
||||||
|
<span v-if="policy.options.protocol == 'socket'">SOCK {{policy.options.socket}}</span>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<label-on :v-is-on="policy.isOn"></label-on>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a :href="Tea.url('.policy', {policyId: policy.id})">详情</a> <a href="" @click.prevent="deletePolicy(policy.id)">删除</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="page" v-html="page"></div>
|
||||||
20
web/views/@default/servers/accesslogs/index.js
Normal file
20
web/views/@default/servers/accesslogs/index.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
this.createPolicy = function () {
|
||||||
|
teaweb.popup(Tea.url(".createPopup", {}), {
|
||||||
|
height: "24em",
|
||||||
|
callback: NotifyReloadSuccess("保存成功")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.deletePolicy = function (policyId) {
|
||||||
|
teaweb.confirm("确定要删除这个日志策略吗?", function () {
|
||||||
|
this.$post(".delete")
|
||||||
|
.params({
|
||||||
|
policyId: policyId
|
||||||
|
})
|
||||||
|
.success(function () {
|
||||||
|
teaweb.successRefresh("保存成功")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
173
web/views/@default/servers/accesslogs/policy.html
Normal file
173
web/views/@default/servers/accesslogs/policy.html
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
{$layout}
|
||||||
|
{$template "policy_menu"}
|
||||||
|
|
||||||
|
<table class="ui table definition selectable">
|
||||||
|
<tr>
|
||||||
|
<td class="title">策略名称</td>
|
||||||
|
<td>
|
||||||
|
{{policy.name}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>状态</td>
|
||||||
|
<td>
|
||||||
|
<label-on :v-is-on="policy.isOn"></label-on>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>存储类型</td>
|
||||||
|
<td>
|
||||||
|
{{policy.typeName}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- 文件 -->
|
||||||
|
<tbody v-if="policy.type == 'file'">
|
||||||
|
<tr>
|
||||||
|
<td>日志文件路径</td>
|
||||||
|
<td>
|
||||||
|
{{policy.options.path}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>是否自动创建目录</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="policy.options.autoCreate" class="green">Y</span>
|
||||||
|
<span v-else class="disabled">N</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- Elastic Search -->
|
||||||
|
<tbody v-if="policy.type == 'es'">
|
||||||
|
<tr>
|
||||||
|
<td>Endpoint</td>
|
||||||
|
<td>
|
||||||
|
{{policy.options.endpoint}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Index</td>
|
||||||
|
<td>
|
||||||
|
{{policy.options.index}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Mapping Type</td>
|
||||||
|
<td>
|
||||||
|
{{policy.options.mappingType}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>认证用户名</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="policy.options.username.length > 0">{{policy.options.username}}</span>
|
||||||
|
<span v-else class="disabled">没有填写。</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>认证密码</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="policy.options.password.length > 0">{{policy.options.password}}</span>
|
||||||
|
<span v-else class="disabled">没有填写。</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- TCP Socket -->
|
||||||
|
<tbody v-if="policy.type == 'tcp'">
|
||||||
|
<tr>
|
||||||
|
<td>网络协议</td>
|
||||||
|
<td>
|
||||||
|
{{policy.options.network.toUpperCase()}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>网络地址</td>
|
||||||
|
<td>
|
||||||
|
{{policy.options.addr}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- Syslog -->
|
||||||
|
<tbody v-if="policy.type == 'syslog'">
|
||||||
|
<tr>
|
||||||
|
<td>网络协议</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="policy.options.protocol == 'none'" class="disabled">[无]</span>
|
||||||
|
<span v-if="policy.options.protocol == 'tcp'">TCP</span>
|
||||||
|
<span v-if="policy.options.protocol == 'udp'">UDP</span>
|
||||||
|
<span v-if="policy.options.protocol == 'socket'">Unix Socket</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr v-if="policy.options.protocol == 'tcp' || policy.options.protocol == 'udp'">
|
||||||
|
<td>网络地址</td>
|
||||||
|
<td>
|
||||||
|
{{policy.options.serverAddr}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-if="policy.options.protocol == 'tcp' || policy.options.protocol == 'udp'">
|
||||||
|
<td>端口</td>
|
||||||
|
<td>
|
||||||
|
{{policy.options.serverPort}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr v-if="policy.options.protocol == 'socket'">
|
||||||
|
<td>Socket路径</td>
|
||||||
|
<td>
|
||||||
|
{{policy.options.socket}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>标签<em>(Tag)</em></td>
|
||||||
|
<td>
|
||||||
|
<span v-if="policy.options.tag.length > 0">{{policy.options.tag}}</span>
|
||||||
|
<span v-else class="disabled">没有设置</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>优先级<em>(Priority)</em></td>
|
||||||
|
<td>
|
||||||
|
{{syslogPriorityName}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- 命令行输入流 -->
|
||||||
|
<tbody v-if="policy.type == 'command'">
|
||||||
|
<tr>
|
||||||
|
<td>可执行命令</td>
|
||||||
|
<td>
|
||||||
|
{{policy.options.command}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>参数</td>
|
||||||
|
<td>
|
||||||
|
<div v-if="policy.options.args != null && policy.options.args.length > 0">
|
||||||
|
<span v-for="arg in policy.options.args" class="ui label basic tiny">{{arg}}</span>
|
||||||
|
</div>
|
||||||
|
<span v-else class="disabled">没有设置参数。</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>工作目录</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="policy.options.dir.length > 0">{{policy.options.dir}}</span>
|
||||||
|
<span v-else class="disabled">没有设置工作目录。</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>是否公用</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="policy.isPublic" class="green">Y</span>
|
||||||
|
<span v-else class="disabled">N</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
18
web/views/@default/servers/accesslogs/test.html
Normal file
18
web/views/@default/servers/accesslogs/test.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{$layout "layout"}
|
||||||
|
{$template "/code_editor"}
|
||||||
|
{$template "policy_menu"}
|
||||||
|
|
||||||
|
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||||
|
<input type="hidden" name="policyId" :value="policy.id"/>
|
||||||
|
<table class="ui table definition selectable">
|
||||||
|
<tr>
|
||||||
|
<td class="title">发送内容</td>
|
||||||
|
<td>
|
||||||
|
<source-code-box id="json-data-box" type="application/json" :read-only="false" name="bodyJSON">{
|
||||||
|
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36"
|
||||||
|
}</source-code-box>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<submit-btn></submit-btn>
|
||||||
|
</form>
|
||||||
5
web/views/@default/servers/accesslogs/test.js
Normal file
5
web/views/@default/servers/accesslogs/test.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
this.success = function () {
|
||||||
|
teaweb.success("发送成功")
|
||||||
|
}
|
||||||
|
})
|
||||||
222
web/views/@default/servers/accesslogs/update.html
Normal file
222
web/views/@default/servers/accesslogs/update.html
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
{$layout}
|
||||||
|
{$template "policy_menu"}
|
||||||
|
|
||||||
|
<h3>修改策略</h3>
|
||||||
|
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||||
|
<csrf-token></csrf-token>
|
||||||
|
<input type="hidden" name="policyId" :value="policy.id"/>
|
||||||
|
|
||||||
|
<table class="ui table definition selectable">
|
||||||
|
<tr>
|
||||||
|
<td class="title">策略名称 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="name" maxlength="50" ref="focus" v-model="policy.name"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>存储类型 *</td>
|
||||||
|
<td>
|
||||||
|
{{policy.typeName}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- 文件 -->
|
||||||
|
<tbody v-show="type == 'file'">
|
||||||
|
<tr>
|
||||||
|
<td>日志文件路径 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="filePath" v-model="policy.options.path"/>
|
||||||
|
<p class="comment">
|
||||||
|
存储日志的文件路径,文件名中支持变量:
|
||||||
|
<span class="ui label tiny">年:${year}</span>
|
||||||
|
<span class="ui label tiny">月:${month}</span>
|
||||||
|
<span class="ui label tiny">周:${week}</span>
|
||||||
|
<span class="ui label tiny">日:${day}</span>
|
||||||
|
<span class="ui label tiny">时:${hour}</span>
|
||||||
|
<span class="ui label tiny">分:${minute}</span>
|
||||||
|
<span class="ui label tiny">秒:${second}</span>
|
||||||
|
<span class="ui label tiny">年月日:${date}</span>,比如<span class="ui label tiny">/var/log/web-access-${date}.log</span>。
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>是否自动创建目录</td>
|
||||||
|
<td>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input type="checkbox" name="fileAutoCreate" value="1" v-model="policy.options.autoCreate"/>
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
<p class="comment">选中后,如果文件目录不存在时可以自动创建。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- Elastic Search -->
|
||||||
|
<tbody v-show="type == 'es'">
|
||||||
|
<tr>
|
||||||
|
<td>Endpoint *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="esEndpoint" v-model="policy.options.endpoint"/>
|
||||||
|
<p class="comment">ES HTTP接口地址,类似于192.168.1.100:9200</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Index *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="esIndex" v-model="policy.options.index"/>
|
||||||
|
<p class="comment">Index名称,支持变量:
|
||||||
|
<span class="ui label tiny">年:${year}</span>
|
||||||
|
<span class="ui label tiny">月:${month}</span>
|
||||||
|
<span class="ui label tiny">周:${week}</span>
|
||||||
|
<span class="ui label tiny">日:${day}</span>
|
||||||
|
<span class="ui label tiny">时:${hour}</span>
|
||||||
|
<span class="ui label tiny">分:${minute}</span>
|
||||||
|
<span class="ui label tiny">秒:${second}</span>
|
||||||
|
<span class="ui label tiny">年月日:${date}</span></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Mapping Type *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="esMappingType" v-model="policy.options.mappingType"/>
|
||||||
|
<p class="comment">Mapping名称,支持变量:
|
||||||
|
<span class="ui label tiny">年:${year}</span>
|
||||||
|
<span class="ui label tiny">月:${month}</span>
|
||||||
|
<span class="ui label tiny">周:${week}</span>
|
||||||
|
<span class="ui label tiny">日:${day}</span>
|
||||||
|
<span class="ui label tiny">时:${hour}</span>
|
||||||
|
<span class="ui label tiny">分:${minute}</span>
|
||||||
|
<span class="ui label tiny">秒:${second}</span>
|
||||||
|
<span class="ui label tiny">年月日:${date}</span></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>认证用户名</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="esUsername" v-model="policy.options.username"/>
|
||||||
|
<p class="comment">配置了认证后才需要填写。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>认证密码</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="esPassword" v-model="policy.options.password"/>
|
||||||
|
<p class="comment">配置了认证后才需要填写。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- TCP Socket -->
|
||||||
|
<tbody v-show="type == 'tcp'">
|
||||||
|
<tr>
|
||||||
|
<td>网络协议 *</td>
|
||||||
|
<td>
|
||||||
|
<select name="tcpNetwork" class="ui dropdown" style="width:10em" v-model="policy.options.network">
|
||||||
|
<option value="tcp">TCP</option>
|
||||||
|
<option value="unix">Unix Socket</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>网络地址 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="tcpAddr" v-model="policy.options.addr"/>
|
||||||
|
<p class="comment">接收日志的网络地址</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- Syslog -->
|
||||||
|
<tbody v-show="type == 'syslog'">
|
||||||
|
<tr>
|
||||||
|
<td>网络协议</td>
|
||||||
|
<td>
|
||||||
|
<select class="ui dropdown" name="syslogProtocol" v-model="syslogProtocol" style="width:10em">
|
||||||
|
<option value="none">[无]</option>
|
||||||
|
<option value="tcp">TCP</option>
|
||||||
|
<option value="udp">UDP</option>
|
||||||
|
<option value="socket">Unix Socket</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr v-if="syslogProtocol == 'tcp' || syslogProtocol == 'udp'">
|
||||||
|
<td>网络地址 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="syslogServerAddr" v-model="policy.options.serverAddr"/>
|
||||||
|
<p class="comment">IP地址或主机名,不包括端口。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-if="syslogProtocol == 'tcp' || syslogProtocol == 'udp'">
|
||||||
|
<td>端口</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="syslogServerPort" v-model="policy.options.serverPort"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr v-if="syslogProtocol == 'socket'">
|
||||||
|
<td>Socket路径 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="syslogSocket" v-model="policy.options.socket"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>标签<em>(Tag)</em></td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="syslogTag" v-model="policy.options.tag"/>
|
||||||
|
<p class="comment">选填项。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>优先级<em>(Priority)</em></td>
|
||||||
|
<td>
|
||||||
|
<select class="ui dropdown" name="syslogPriority" style="width:10em" v-model="policy.options.priority">
|
||||||
|
<option v-for="priority in syslogPriorities" :value="priority.value">{{priority.name}}</option>
|
||||||
|
</select>
|
||||||
|
<p class="comment">选填项。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- 命令行输入流 -->
|
||||||
|
<tbody v-show="type == 'command'">
|
||||||
|
<tr>
|
||||||
|
<td>可执行命令 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="commandCommand" v-model="policy.options.command"/>
|
||||||
|
<p class="comment">不带参数的可执行命令地址</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>参数</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="commandArgs" v-model="policy.options.args"/>
|
||||||
|
<p class="comment">执行命令需要的参数</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>工作目录</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="commandDir" v-model="policy.options.dir"/>
|
||||||
|
<p class="comment">命令执行所在的工作目录</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>是否公用</td>
|
||||||
|
<td>
|
||||||
|
<checkbox name="isPublic" v-model="policy.isPublic"></checkbox>
|
||||||
|
<p class="comment">选中后表示自动将此策略应用于所有集群,同时只会有一个公用策略。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>是否启用</td>
|
||||||
|
<td>
|
||||||
|
<checkbox name="isOn" v-model="policy.isOn"></checkbox>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<submit-btn></submit-btn>
|
||||||
|
</form>
|
||||||
24
web/views/@default/servers/accesslogs/update.js
Normal file
24
web/views/@default/servers/accesslogs/update.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
this.success = NotifySuccess("html:保存成功<br/>新的配置将会在1分钟之内生效", ".policy", {policyId: this.policy.id})
|
||||||
|
|
||||||
|
this.type = this.policy.type
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* syslog
|
||||||
|
*/
|
||||||
|
this.syslogProtocol = this.policy.options.protocol
|
||||||
|
|
||||||
|
/**
|
||||||
|
* command
|
||||||
|
*/
|
||||||
|
if (this.policy.type == "command") {
|
||||||
|
let args = this.policy.options.args
|
||||||
|
if (args == null) {
|
||||||
|
args = ""
|
||||||
|
} else {
|
||||||
|
args = args.join(" ")
|
||||||
|
}
|
||||||
|
this.policy.options.args = args
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -8,8 +8,7 @@
|
|||||||
<http-access-log-config-box
|
<http-access-log-config-box
|
||||||
:v-access-log-config="accessLogConfig"
|
:v-access-log-config="accessLogConfig"
|
||||||
:v-fields="fields"
|
:v-fields="fields"
|
||||||
:v-default-field-codes="defaultFieldCodes"
|
:v-default-field-codes="defaultFieldCodes"></http-access-log-config-box>
|
||||||
:v-access-log-policies="accessLogPolicies"></http-access-log-config-box>
|
|
||||||
<submit-btn></submit-btn>
|
<submit-btn></submit-btn>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
:v-access-log-config="accessLogConfig"
|
:v-access-log-config="accessLogConfig"
|
||||||
:v-fields="fields"
|
:v-fields="fields"
|
||||||
:v-default-field-codes="defaultFieldCodes"
|
:v-default-field-codes="defaultFieldCodes"
|
||||||
:v-access-log-policies="accessLogPolicies"
|
|
||||||
:v-is-location="true"></http-access-log-config-box>
|
:v-is-location="true"></http-access-log-config-box>
|
||||||
<submit-btn></submit-btn>
|
<submit-btn></submit-btn>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
Reference in New Issue
Block a user