改进界面

This commit is contained in:
GoEdgeLab
2021-06-05 16:53:26 +08:00
parent 47edae4490
commit b0dedb653e
33 changed files with 575 additions and 115 deletions

View File

@@ -2,6 +2,7 @@ package node
import ( import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time" timeutil "github.com/iwind/TeaGo/utils/time"
@@ -18,7 +19,18 @@ func (this *LogsAction) Init() {
func (this *LogsAction) RunGet(params struct { func (this *LogsAction) RunGet(params struct {
NodeId int64 NodeId int64
DayFrom string
DayTo string
Keyword string
Level string
}) { }) {
this.Data["nodeId"] = params.NodeId
this.Data["dayFrom"] = params.DayFrom
this.Data["dayTo"] = params.DayTo
this.Data["keyword"] = params.Keyword
this.Data["level"] = params.Level
apiNodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{NodeId: params.NodeId}) apiNodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{NodeId: params.NodeId})
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)
@@ -36,8 +48,12 @@ func (this *LogsAction) RunGet(params struct {
} }
countResp, err := this.RPC().NodeLogRPC().CountNodeLogs(this.AdminContext(), &pb.CountNodeLogsRequest{ countResp, err := this.RPC().NodeLogRPC().CountNodeLogs(this.AdminContext(), &pb.CountNodeLogsRequest{
Role: "api", Role: nodeconfigs.NodeRoleAPI,
NodeId: params.NodeId, NodeId: params.NodeId,
DayFrom: params.DayFrom,
DayTo: params.DayTo,
Keyword: params.Keyword,
Level: params.Level,
}) })
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)
@@ -47,8 +63,13 @@ func (this *LogsAction) RunGet(params struct {
page := this.NewPage(count, 20) page := this.NewPage(count, 20)
logsResp, err := this.RPC().NodeLogRPC().ListNodeLogs(this.AdminContext(), &pb.ListNodeLogsRequest{ logsResp, err := this.RPC().NodeLogRPC().ListNodeLogs(this.AdminContext(), &pb.ListNodeLogsRequest{
NodeId: params.NodeId, NodeId: params.NodeId,
Role: "api", Role: nodeconfigs.NodeRoleAPI,
DayFrom: params.DayFrom,
DayTo: params.DayTo,
Keyword: params.Keyword,
Level: params.Level,
Offset: page.Offset, Offset: page.Offset,
Size: page.Size, Size: page.Size,
}) })

View File

@@ -29,13 +29,7 @@ func (this *IndexAction) RunGet(params struct {
this.Data["searchType"] = params.SearchType this.Data["searchType"] = params.SearchType
this.Data["isSearching"] = isSearching this.Data["isSearching"] = isSearching
// 搜索节点 // 常用的集群
if params.SearchType == "node" && len(params.Keyword) > 0 {
this.searchNodes(params.Keyword)
return
}
// 常用的节点
latestClusterMaps := []maps.Map{} latestClusterMaps := []maps.Map{}
if !isSearching { if !isSearching {
clustersResp, err := this.RPC().NodeClusterRPC().FindLatestNodeClusters(this.AdminContext(), &pb.FindLatestNodeClustersRequest{Size: 6}) clustersResp, err := this.RPC().NodeClusterRPC().FindLatestNodeClusters(this.AdminContext(), &pb.FindLatestNodeClustersRequest{Size: 6})
@@ -52,6 +46,12 @@ func (this *IndexAction) RunGet(params struct {
} }
this.Data["latestClusters"] = latestClusterMaps this.Data["latestClusters"] = latestClusterMaps
// 搜索节点
if params.SearchType == "node" && len(params.Keyword) > 0 {
this.searchNodes(params.Keyword)
return
}
// 搜索集群 // 搜索集群
countResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClusters(this.AdminContext(), &pb.CountAllEnabledNodeClustersRequest{ countResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClusters(this.AdminContext(), &pb.CountAllEnabledNodeClustersRequest{
Keyword: params.Keyword, Keyword: params.Keyword,

View File

@@ -17,6 +17,7 @@ func init() {
// 节点相关 // 节点相关
Helper(NewHelper()). Helper(NewHelper()).
Get("", new(IndexAction)). Get("", new(IndexAction)).
Get("/logs", new(LogsAction)).
GetPost("/update", new(UpdateAction)). GetPost("/update", new(UpdateAction)).
Get("/install", new(InstallAction)). Get("/install", new(InstallAction)).

View File

@@ -0,0 +1,92 @@
package node
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time"
)
type LogsAction struct {
actionutils.ParentAction
}
func (this *LogsAction) Init() {
this.Nav("", "node", "log")
this.SecondMenu("nodes")
}
func (this *LogsAction) RunGet(params struct {
NodeId int64
DayFrom string
DayTo string
Keyword string
Level string
}) {
this.Data["nodeId"] = params.NodeId
this.Data["dayFrom"] = params.DayFrom
this.Data["dayTo"] = params.DayTo
this.Data["keyword"] = params.Keyword
this.Data["level"] = params.Level
apiNodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{NodeId: params.NodeId})
if err != nil {
this.ErrorPage(err)
return
}
apiNode := apiNodeResp.Node
if apiNode == nil {
this.NotFound("apiNode", params.NodeId)
return
}
this.Data["node"] = maps.Map{
"id": apiNode.Id,
"name": apiNode.Name,
}
countResp, err := this.RPC().NodeLogRPC().CountNodeLogs(this.AdminContext(), &pb.CountNodeLogsRequest{
Role: nodeconfigs.NodeRoleAuthority,
NodeId: params.NodeId,
DayFrom: params.DayFrom,
DayTo: params.DayTo,
Keyword: params.Keyword,
Level: params.Level,
})
if err != nil {
this.ErrorPage(err)
return
}
count := countResp.Count
page := this.NewPage(count, 20)
logsResp, err := this.RPC().NodeLogRPC().ListNodeLogs(this.AdminContext(), &pb.ListNodeLogsRequest{
NodeId: params.NodeId,
Role: nodeconfigs.NodeRoleAuthority,
DayFrom: params.DayFrom,
DayTo: params.DayTo,
Keyword: params.Keyword,
Level: params.Level,
Offset: page.Offset,
Size: page.Size,
})
logs := []maps.Map{}
for _, log := range logsResp.NodeLogs {
logs = append(logs, maps.Map{
"tag": log.Tag,
"description": log.Description,
"createdTime": timeutil.FormatTime("Y-m-d H:i:s", log.CreatedAt),
"level": log.Level,
"isToday": timeutil.FormatTime("Y-m-d", log.CreatedAt) == timeutil.Format("Y-m-d"),
})
}
this.Data["logs"] = logs
this.Data["page"] = page.AsHTML()
this.Show()
}

View File

@@ -17,6 +17,7 @@ func init() {
// 节点相关 // 节点相关
Helper(NewHelper()). Helper(NewHelper()).
Get("", new(IndexAction)). Get("", new(IndexAction)).
Get("/logs", new(LogsAction)).
GetPost("/update", new(UpdateAction)). GetPost("/update", new(UpdateAction)).
Get("/install", new(InstallAction)). Get("/install", new(InstallAction)).

View File

@@ -0,0 +1,92 @@
package node
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time"
)
type LogsAction struct {
actionutils.ParentAction
}
func (this *LogsAction) Init() {
this.Nav("", "node", "log")
this.SecondMenu("nodes")
}
func (this *LogsAction) RunGet(params struct {
NodeId int64
DayFrom string
DayTo string
Keyword string
Level string
}) {
this.Data["nodeId"] = params.NodeId
this.Data["dayFrom"] = params.DayFrom
this.Data["dayTo"] = params.DayTo
this.Data["keyword"] = params.Keyword
this.Data["level"] = params.Level
apiNodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{NodeId: params.NodeId})
if err != nil {
this.ErrorPage(err)
return
}
apiNode := apiNodeResp.Node
if apiNode == nil {
this.NotFound("apiNode", params.NodeId)
return
}
this.Data["node"] = maps.Map{
"id": apiNode.Id,
"name": apiNode.Name,
}
countResp, err := this.RPC().NodeLogRPC().CountNodeLogs(this.AdminContext(), &pb.CountNodeLogsRequest{
Role: nodeconfigs.NodeRoleMonitor,
NodeId: params.NodeId,
DayFrom: params.DayFrom,
DayTo: params.DayTo,
Keyword: params.Keyword,
Level: params.Level,
})
if err != nil {
this.ErrorPage(err)
return
}
count := countResp.Count
page := this.NewPage(count, 20)
logsResp, err := this.RPC().NodeLogRPC().ListNodeLogs(this.AdminContext(), &pb.ListNodeLogsRequest{
NodeId: params.NodeId,
Role: nodeconfigs.NodeRoleMonitor,
DayFrom: params.DayFrom,
DayTo: params.DayTo,
Keyword: params.Keyword,
Level: params.Level,
Offset: page.Offset,
Size: page.Size,
})
logs := []maps.Map{}
for _, log := range logsResp.NodeLogs {
logs = append(logs, maps.Map{
"tag": log.Tag,
"description": log.Description,
"createdTime": timeutil.FormatTime("Y-m-d H:i:s", log.CreatedAt),
"level": log.Level,
"isToday": timeutil.FormatTime("Y-m-d", log.CreatedAt) == timeutil.Format("Y-m-d"),
})
}
this.Data["logs"] = logs
this.Data["page"] = page.AsHTML()
this.Show()
}

View File

@@ -21,6 +21,7 @@ func init() {
// 节点相关 // 节点相关
Helper(NewHelper()). Helper(NewHelper()).
Get("", new(IndexAction)). Get("", new(IndexAction)).
Get("/logs", new(LogsAction)).
GetPost("/update", new(UpdateAction)). GetPost("/update", new(UpdateAction)).
Get("/install", new(InstallAction)). Get("/install", new(InstallAction)).

View File

@@ -0,0 +1,92 @@
package node
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time"
)
type LogsAction struct {
actionutils.ParentAction
}
func (this *LogsAction) Init() {
this.Nav("", "node", "log")
this.SecondMenu("nodes")
}
func (this *LogsAction) RunGet(params struct {
NodeId int64
DayFrom string
DayTo string
Keyword string
Level string
}) {
this.Data["nodeId"] = params.NodeId
this.Data["dayFrom"] = params.DayFrom
this.Data["dayTo"] = params.DayTo
this.Data["keyword"] = params.Keyword
this.Data["level"] = params.Level
apiNodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{NodeId: params.NodeId})
if err != nil {
this.ErrorPage(err)
return
}
apiNode := apiNodeResp.Node
if apiNode == nil {
this.NotFound("apiNode", params.NodeId)
return
}
this.Data["node"] = maps.Map{
"id": apiNode.Id,
"name": apiNode.Name,
}
countResp, err := this.RPC().NodeLogRPC().CountNodeLogs(this.AdminContext(), &pb.CountNodeLogsRequest{
Role: nodeconfigs.NodeRoleUser,
NodeId: params.NodeId,
DayFrom: params.DayFrom,
DayTo: params.DayTo,
Keyword: params.Keyword,
Level: params.Level,
})
if err != nil {
this.ErrorPage(err)
return
}
count := countResp.Count
page := this.NewPage(count, 20)
logsResp, err := this.RPC().NodeLogRPC().ListNodeLogs(this.AdminContext(), &pb.ListNodeLogsRequest{
NodeId: params.NodeId,
Role: nodeconfigs.NodeRoleUser,
DayFrom: params.DayFrom,
DayTo: params.DayTo,
Keyword: params.Keyword,
Level: params.Level,
Offset: page.Offset,
Size: page.Size,
})
logs := []maps.Map{}
for _, log := range logsResp.NodeLogs {
logs = append(logs, maps.Map{
"tag": log.Tag,
"description": log.Description,
"createdTime": timeutil.FormatTime("Y-m-d H:i:s", log.CreatedAt),
"level": log.Level,
"isToday": timeutil.FormatTime("Y-m-d", log.CreatedAt) == timeutil.Format("Y-m-d"),
})
}
this.Data["logs"] = logs
this.Data["page"] = page.AsHTML()
this.Show()
}

View File

@@ -0,0 +1,12 @@
Vue.component("node-log-row", {
props: ["v-log", "v-keyword"],
data: function () {
return {
log: this.vLog,
keyword: this.vKeyword
}
},
template: `<div>
<pre class="log-box" style="margin: 0; padding: 0"><span :class="{red:log.level == 'error', orange:log.level == 'warning'}"><span v-if="!log.isToday">[{{log.createdTime}}]</span><strong v-if="log.isToday">[{{log.createdTime}}]</strong><keyword :v-word="keyword">[{{log.tag}}]{{log.description}}</keyword></span> &nbsp; <span v-if="log.count > 0" class="ui label tiny" :class="{red:log.level == 'error', orange:log.level == 'warning'}">共{{log.count}}条</span></pre>
</div>`
})

View File

@@ -1,4 +1,3 @@
{$var "header"} {$var "header"}
<!-- code editor --> <!-- code editor -->
<script src="/codemirror/lib/codemirror.js" type="text/javascript"></script> <script src="/codemirror/lib/codemirror.js" type="text/javascript"></script>

View File

@@ -0,0 +1,8 @@
{$var "header"}
<!-- datepicker -->
<script type="text/javascript" src="/js/moment.min.js"></script>
<script type="text/javascript" src="/js/pikaday.js"></script>
<link rel="stylesheet" href="/js/pikaday.css"/>
<link rel="stylesheet" href="/js/pikaday.theme.css"/>
<link rel="stylesheet" href="/js/pikaday.triangle.css"/>
{$end}

View File

@@ -1,20 +1,50 @@
{$layout} {$layout}
{$template "menu"}
{$template "/datepicker"}
{$template "menu"} <div class="margin"></div>
<form method="get" action="/api/node/logs" class="ui form" autocomplete="off">
<input type="hidden" name="nodeId" :value="nodeId"/>
<div class="ui fields inline">
<div class="ui field">
<input type="text" name="dayFrom" placeholder="开始日期" v-model="dayFrom" value="" style="width:8em" id="day-from-picker"/>
</div>
<div class="ui field">
<input type="text" name="dayTo" placeholder="结束日期" v-model="dayTo" value="" style="width:8em" id="day-to-picker"/>
</div>
<div class="ui field">
<select class="ui dropdown" name="level" v-model="level">
<option value="">[级别]</option>
<option value="error">错误</option>
<option value="warning">警告</option>
<option value="info">信息</option>
</select>
</div>
<div class="ui field">
<input type="text" name="keyword" style="width:10em" v-model="keyword" placeholder="关键词"/>
</div>
<div class="ui field">
<button type="submit" class="ui button">查询</button>
</div>
<div class="ui field" v-if="dayFrom.length > 0 || dayTo.length > 0 || keyword.length > 0 || level.length > 0">
<a :href="'/api/node/logs?nodeId=' + nodeId">[清除条件]</a>
</div>
</div>
</form>
<p class="comment" v-if="logs.length == 0">暂时还没有日志。</p> <p class="comment" v-if="logs.length == 0">暂时还没有日志。</p>
<table class="ui table selectable" v-if="logs.length > 0"> <table class="ui table selectable" v-if="logs.length > 0">
<thead> <thead>
<tr> <tr>
</tr> </tr>
</thead> </thead>
<tr v-for="log in logs"> <tr v-for="log in logs">
<td> <td>
<pre class="log-box"><span :class="{red:log.level == 'error', orange:log.level == 'warning'}"><span v-if="!log.isToday">[{{log.createdTime}}]</span><strong v-if="log.isToday">[{{log.createdTime}}]</strong>[{{log.tag}}]{{log.description}}</span></pre> <node-log-row :v-log="log" :v-keyword="keyword"></node-log-row>
</td> </td>
</tr> </tr>
</table> </table>
<div class="page" v-html="page"></div> <div class="page" v-html="page"></div>

View File

@@ -0,0 +1,6 @@
Tea.context(function () {
this.$delay(function () {
teaweb.datepicker("day-from-picker")
teaweb.datepicker("day-to-picker")
})
})

View File

@@ -1,14 +1,6 @@
{$layout} {$layout}
{$template "node_menu"} {$template "node_menu"}
{$template "/datepicker"}
{$var "header"}
<!-- datepicker -->
<script type="text/javascript" src="/js/moment.min.js"></script>
<script type="text/javascript" src="/js/pikaday.js"></script>
<link rel="stylesheet" href="/js/pikaday.css"/>
<link rel="stylesheet" href="/js/pikaday.theme.css"/>
<link rel="stylesheet" href="/js/pikaday.triangle.css"/>
{$end}
<form method="get" action="/clusters/cluster/node/logs" class="ui form" autocomplete="off"> <form method="get" action="/clusters/cluster/node/logs" class="ui form" autocomplete="off">
<input type="hidden" name="clusterId" :value="clusterId"/> <input type="hidden" name="clusterId" :value="clusterId"/>
@@ -50,7 +42,7 @@
</thead> </thead>
<tr v-for="log in logs"> <tr v-for="log in logs">
<td> <td>
<pre class="log-box"><span :class="{red:log.level == 'error', orange:log.level == 'warning'}"><span v-if="!log.isToday">[{{log.createdTime}}]</span><strong v-if="log.isToday">[{{log.createdTime}}]</strong>[{{log.tag}}]{{log.description}}</span> &nbsp; <span v-if="log.count > 0" class="ui label tiny" :class="{red:log.level == 'error', orange:log.level == 'warning'}">共{{log.count}}条</span></pre> <node-log-row :v-log="log" :v-keyword="keyword"></node-log-row>
</td> </td>
</tr> </tr>
</table> </table>

View File

@@ -40,7 +40,7 @@
</tr> </tr>
</thead> </thead>
<tr v-for="cluster in clusters"> <tr v-for="cluster in clusters">
<td>{{cluster.name}}</td> <td><keyword :v-word="keyword">{{cluster.name}}</keyword></td>
<td class="center"> <td class="center">
<a :href="'/clusters/cluster?clusterId=' + cluster.id" v-if="cluster.countAllNodes > 0"><span :class="{red:cluster.countAllNodes > cluster.countActiveNodes}">{{cluster.countAllNodes}}</span></a> <a :href="'/clusters/cluster?clusterId=' + cluster.id" v-if="cluster.countAllNodes > 0"><span :class="{red:cluster.countAllNodes > cluster.countActiveNodes}">{{cluster.countAllNodes}}</span></a>
<span class="disabled" v-else="">-</span> <span class="disabled" v-else="">-</span>
@@ -55,7 +55,7 @@
</td> </td>
<td> <td>
<span v-if="cluster.dnsName.length > 0"> <span v-if="cluster.dnsName.length > 0">
<var>{{cluster.dnsName}}</var>.<span v-if="cluster.dnsDomainName.length > 0">{{cluster.dnsDomainName}}</span><span v-else class="disabled">主域名</span> <var><keyword :v-word="keyword">{{cluster.dnsName}}</keyword></var>.<span v-if="cluster.dnsDomainName.length > 0">{{cluster.dnsDomainName}}</span><span v-else class="disabled">主域名</span>
<span v-if="cluster.dnsDomainId > 0"><link-icon :href="'/dns/clusters/cluster?clusterId=' + cluster.id"></link-icon></span> <span v-if="cluster.dnsDomainId > 0"><link-icon :href="'/dns/clusters/cluster?clusterId=' + cluster.id"></link-icon></span>
</span> </span>
<span v-else class="disabled">-</span> <span v-else class="disabled">-</span>
@@ -86,7 +86,7 @@
</tr> </tr>
</thead> </thead>
<tr v-for="node in nodes"> <tr v-for="node in nodes">
<td>{{node.name}} <td><keyword :v-word="keyword">{{node.name}}</keyword>
<div style="margin-top: 0.5em"> <div style="margin-top: 0.5em">
<span class="ui label tiny">集群:{{node.cluster.name}}</span> <span class="ui label tiny">集群:{{node.cluster.name}}</span>
</div> </div>
@@ -103,7 +103,7 @@
<span v-if="node.ipAddresses.length == 0" class="disabled">-</span> <span v-if="node.ipAddresses.length == 0" class="disabled">-</span>
<div v-else class="address-box"> <div v-else class="address-box">
<div v-for="addr in node.ipAddresses" style="margin-bottom:0.3em"> <div v-for="addr in node.ipAddresses" style="margin-bottom:0.3em">
<div class="ui label tiny basic">{{addr.ip}} <div class="ui label tiny basic"><keyword :v-word="keyword">{{addr.ip}}</keyword>
<span class="small" v-if="addr.name.length > 0">{{addr.name}}<span v-if="!addr.canAccess">,不可访问</span></span> <span class="small" v-if="addr.name.length > 0">{{addr.name}}<span v-if="!addr.canAccess">,不可访问</span></span>
<span class="small" v-if="addr.name.length == 0 && !addr.canAccess">(不可访问)</span> <span class="small" v-if="addr.name.length == 0 && !addr.canAccess">(不可访问)</span>
</div> </div>

View File

@@ -1,14 +1,5 @@
{$layout} {$layout}
{$template "/datepicker"}
{$var "header"}
<!-- datepicker -->
<script type="text/javascript" src="/js/moment.min.js"></script>
<script type="text/javascript" src="/js/pikaday.js"></script>
<link rel="stylesheet" href="/js/pikaday.css"/>
<link rel="stylesheet" href="/js/pikaday.theme.css"/>
<link rel="stylesheet" href="/js/pikaday.triangle.css"/>
{$end}
<div class="margin"></div> <div class="margin"></div>
@@ -54,7 +45,7 @@
<td nowrap=""><link-icon :href="'/clusters/cluster?clusterId=' + log.node.cluster.id">{{log.node.cluster.name}}</link-icon></td> <td nowrap=""><link-icon :href="'/clusters/cluster?clusterId=' + log.node.cluster.id">{{log.node.cluster.name}}</link-icon></td>
<td nowrap=""><link-icon :href="'/clusters/cluster/node?clusterId=' + log.node.cluster.id + '&nodeId=' + log.node.id">{{log.node.name}}</link-icon></td> <td nowrap=""><link-icon :href="'/clusters/cluster/node?clusterId=' + log.node.cluster.id + '&nodeId=' + log.node.id">{{log.node.name}}</link-icon></td>
<td> <td>
<pre class="log-box"><span :class="{red:log.level == 'error', orange:log.level == 'warning'}"><span v-if="!log.isToday">[{{log.createdTime}}]</span><strong v-if="log.isToday">[{{log.createdTime}}]</strong>[{{log.tag}}]{{log.description}}</span> &nbsp; <span v-if="log.count > 0" class="ui label tiny" :class="{red:log.level == 'error', orange:log.level == 'warning'}">共{{log.count}}条</span></pre> <node-log-row :v-log="log" :v-keyword="keyword"></node-log-row>
</td> </td>
</tr> </tr>
</table> </table>

View File

@@ -1,14 +1,6 @@
{$layout} {$layout}
{$template "menu"} {$template "menu"}
{$template "/datepicker"}
{$var "header"}
<!-- datepicker -->
<script type="text/javascript" src="/js/moment.min.js"></script>
<script type="text/javascript" src="/js/pikaday.js"></script>
<link rel="stylesheet" href="/js/pikaday.css"/>
<link rel="stylesheet" href="/js/pikaday.theme.css"/>
<link rel="stylesheet" href="/js/pikaday.triangle.css"/>
{$end}
<div class="margin"></div> <div class="margin"></div>
@@ -50,13 +42,13 @@
<table class="ui table selectable" v-for="log in logs"> <table class="ui table selectable" v-for="log in logs">
<tr :class="{error: log.level == 'error', warning: log.level == 'warn'}"> <tr :class="{error: log.level == 'error', warning: log.level == 'warn'}">
<td class="log-row">{{log.createdTime}} <span class="grey"> <span <td class="log-row">{{log.createdTime}} <span class="grey"> <span
v-if="log.userName.length > 0">| <span v-if="log.userId>0">用户 &nbsp;|&nbsp;</span> {{log.userName}}</span> | {{log.ip}}<span v-if="log.userName.length > 0">| <span v-if="log.userId>0">用户 &nbsp;|&nbsp;</span> {{log.userName}}</span> | <keyword :v-word="keyword">{{log.ip}}</keyword><span
v-if="log.region.length > 0"> | {{log.region}}</span> &nbsp; <a href="" @click.prevent="showMore(log)" title="显示更多">...</a> &nbsp;<span v-if="log.moreVisible">{{log.action}}</span></span> v-if="log.region.length > 0"> | {{log.region}}</span> &nbsp; <a href="" @click.prevent="showMore(log)" title="显示更多">...</a> &nbsp;<span v-if="log.moreVisible">{{log.action}}</span></span>
<span class="buttons"><a v-if="logConfig.canDelete" href="" title="删除" @click.prevent="deleteLog(log.id)"><i class="icon remove small"></i></a> </span> <span class="buttons"><a v-if="logConfig.canDelete" href="" title="删除" @click.prevent="deleteLog(log.id)"><i class="icon remove small"></i></a> </span>
</td> </td>
</tr> </tr>
<tr :class="{error: log.level == 'error', warning: log.level == 'warn'}"> <tr :class="{error: log.level == 'error', warning: log.level == 'warn'}">
<td>{{log.description}}</td> <td><keyword :v-word="keyword">{{log.description}}</keyword></td>
</tr> </tr>
</table> </table>

View File

@@ -1,13 +1,5 @@
{$layout} {$layout}
{$template "/datepicker"}
{$var "header"}
<!-- datepicker -->
<script type="text/javascript" src="/js/moment.min.js"></script>
<script type="text/javascript" src="/js/pikaday.js"></script>
<link rel="stylesheet" href="/js/pikaday.css"/>
<link rel="stylesheet" href="/js/pikaday.theme.css"/>
<link rel="stylesheet" href="/js/pikaday.triangle.css"/>
{$end}
<first-menu> <first-menu>
<div class="item right"> <div class="item right">

View File

@@ -1,14 +1,6 @@
{$layout} {$layout}
{$template "node_menu"} {$template "node_menu"}
{$template "/datepicker"}
{$var "header"}
<!-- datepicker -->
<script type="text/javascript" src="/js/moment.min.js"></script>
<script type="text/javascript" src="/js/pikaday.js"></script>
<link rel="stylesheet" href="/js/pikaday.css"/>
<link rel="stylesheet" href="/js/pikaday.theme.css"/>
<link rel="stylesheet" href="/js/pikaday.triangle.css"/>
{$end}
<form method="get" action="/ns/clusters/cluster/node/logs" class="ui form" autocomplete="off"> <form method="get" action="/ns/clusters/cluster/node/logs" class="ui form" autocomplete="off">
<input type="hidden" name="clusterId" :value="clusterId"/> <input type="hidden" name="clusterId" :value="clusterId"/>
@@ -50,7 +42,7 @@
</thead> </thead>
<tr v-for="log in logs"> <tr v-for="log in logs">
<td> <td>
<pre class="log-box"><span :class="{red:log.level == 'error', orange:log.level == 'warning'}"><span v-if="!log.isToday">[{{log.createdTime}}]</span><strong v-if="log.isToday">[{{log.createdTime}}]</strong>[{{log.tag}}]{{log.description}}</span> &nbsp; <span v-if="log.count > 0" class="ui label tiny" :class="{red:log.level == 'error', orange:log.level == 'warning'}">共{{log.count}}条</span></pre> <node-log-row :v-log="log" :v-keyword="keyword"></node-log-row>
</td> </td>
</tr> </tr>
</table> </table>

View File

@@ -1,13 +1,5 @@
{$layout} {$layout}
{$template "/datepicker"}
{$var "header"}
<!-- datepicker -->
<script type="text/javascript" src="/js/moment.min.js"></script>
<script type="text/javascript" src="/js/pikaday.js"></script>
<link rel="stylesheet" href="/js/pikaday.css"/>
<link rel="stylesheet" href="/js/pikaday.theme.css"/>
<link rel="stylesheet" href="/js/pikaday.triangle.css"/>
{$end}
<div class="margin"></div> <div class="margin"></div>
@@ -54,7 +46,7 @@
<td nowrap=""><link-icon :href="'/ns/clusters/cluster?clusterId=' + log.node.cluster.id">{{log.node.cluster.name}}</link-icon></td> <td nowrap=""><link-icon :href="'/ns/clusters/cluster?clusterId=' + log.node.cluster.id">{{log.node.cluster.name}}</link-icon></td>
<td nowrap=""><link-icon :href="'/ns/clusters/cluster/node?clusterId=' + log.node.cluster.id + '&nodeId=' + log.node.id">{{log.node.name}}</link-icon></td> <td nowrap=""><link-icon :href="'/ns/clusters/cluster/node?clusterId=' + log.node.cluster.id + '&nodeId=' + log.node.id">{{log.node.name}}</link-icon></td>
<td> <td>
<pre class="log-box"><span :class="{red:log.level == 'error', orange:log.level == 'warning'}"><span v-if="!log.isToday">[{{log.createdTime}}]</span><strong v-if="log.isToday">[{{log.createdTime}}]</strong>[{{log.tag}}]{{log.description}}</span> &nbsp; <span v-if="log.count > 0" class="ui label tiny" :class="{red:log.level == 'error', orange:log.level == 'warning'}">共{{log.count}}条</span></pre> <node-log-row :v-log="log" :v-keyword="keyword"></node-log-row>
</td> </td>
</tr> </tr>
</table> </table>

View File

@@ -17,7 +17,7 @@
<ns-user-selector :v-user-id="userId"></ns-user-selector> <ns-user-selector :v-user-id="userId"></ns-user-selector>
</div> </div>
<div class="ui field"> <div class="ui field">
<input type="text" name="keyword" v-model="keyword" placeholder="域名、备注..."/> <input type="text" name="keyword" v-model="keyword" placeholder="域名..."/>
</div> </div>
<div class="ui field"> <div class="ui field">
<button class="ui button" type="submit">搜索</button> <button class="ui button" type="submit">搜索</button>
@@ -42,7 +42,7 @@
</tr> </tr>
</thead> </thead>
<tr v-for="domain in domains"> <tr v-for="domain in domains">
<td>{{domain.name}}</td> <td><keyword :v-word="keyword">{{domain.name}}</keyword></td>
<td> <td>
{{domain.cluster.name}}<link-icon :href="'/ns/clusters/cluster?clusterId=' + domain.cluster.id"></link-icon> {{domain.cluster.name}}<link-icon :href="'/ns/clusters/cluster?clusterId=' + domain.cluster.id"></link-icon>
</td> </td>

View File

@@ -1,14 +1,5 @@
{$layout} {$layout}
{$template "/datepicker"}
{$var "header"}
<!-- datepicker -->
<script type="text/javascript" src="/js/moment.min.js"></script>
<script type="text/javascript" src="/js/pikaday.js"></script>
<link rel="stylesheet" href="/js/pikaday.css"/>
<link rel="stylesheet" href="/js/pikaday.theme.css"/>
<link rel="stylesheet" href="/js/pikaday.triangle.css"/>
{$end}
{$template "waf_menu"} {$template "waf_menu"}

View File

@@ -73,7 +73,7 @@
</tr> </tr>
</thead> </thead>
<tr v-for="server in servers"> <tr v-for="server in servers">
<td>{{server.name}} <td><keyword :v-word="keyword">{{server.name}}</keyword>
<div style="margin-top:0.4em"> <div style="margin-top:0.4em">
<tiny-basic-label>{{server.serverTypeName}}</tiny-basic-label> <tiny-basic-label>{{server.serverTypeName}}</tiny-basic-label>
</div> </div>
@@ -85,8 +85,8 @@
<td>{{server.cluster.name}}</td> <td>{{server.cluster.name}}</td>
<td> <td>
<span v-if="server.serverNames.length > 0"> <span v-if="server.serverNames.length > 0">
<span v-if="server.serverNames[0].subNames == null || server.serverNames[0].subNames.length == 0">{{server.serverNames[0].name}}</span> <span v-if="server.serverNames[0].subNames == null || server.serverNames[0].subNames.length == 0"><keyword :v-word="keyword">{{server.serverNames[0].name}}</keyword></span>
<span v-else>{{server.serverNames[0].subNames[0]}}</span> <span v-else><keyword :v-word="keyword">{{server.serverNames[0].subNames[0]}}</keyword></span>
<span v-if="server.countServerNames > 1">等{{server.countServerNames}}个域名 <popup-icon :href="'/servers/serverNamesPopup?serverId=' + server.id" height="20em"></popup-icon></span> <span v-if="server.countServerNames > 1">等{{server.countServerNames}}个域名 <popup-icon :href="'/servers/serverNamesPopup?serverId=' + server.id" height="20em"></popup-icon></span>
</span> </span>
<span v-else class="disabled">-</span> <span v-else class="disabled">-</span>

View File

@@ -1,13 +1,5 @@
{$layout} {$layout}
{$template "/datepicker"}
{$var "header"}
<!-- datepicker -->
<script type="text/javascript" src="/js/moment.min.js"></script>
<script type="text/javascript" src="/js/pikaday.js"></script>
<link rel="stylesheet" href="/js/pikaday.css"/>
<link rel="stylesheet" href="/js/pikaday.theme.css"/>
<link rel="stylesheet" href="/js/pikaday.triangle.css"/>
{$end}
{$template "/left_menu"} {$template "/left_menu"}

View File

@@ -2,6 +2,7 @@
<menu-item href="/settings/authority/nodes">节点列表</menu-item> <menu-item href="/settings/authority/nodes">节点列表</menu-item>
<span class="item">|</span> <span class="item">|</span>
<menu-item :href="'/settings/authority/nodes/node?nodeId=' + node.id" code="index">"{{node.name}}"详情</menu-item> <menu-item :href="'/settings/authority/nodes/node?nodeId=' + node.id" code="index">"{{node.name}}"详情</menu-item>
<menu-item :href="'/settings/authority/nodes/node/logs?nodeId=' + node.id" code="log">运行日志</menu-item>
<menu-item :href="'/settings/authority/nodes/node/install?nodeId=' + node.id" code="install">安装节点</menu-item> <menu-item :href="'/settings/authority/nodes/node/install?nodeId=' + node.id" code="install">安装节点</menu-item>
<menu-item :href="'/settings/authority/nodes/node/update?nodeId=' + node.id" code="update">修改节点</menu-item> <menu-item :href="'/settings/authority/nodes/node/update?nodeId=' + node.id" code="update">修改节点</menu-item>
</first-menu> </first-menu>

View File

@@ -0,0 +1,50 @@
{$layout}
{$template "menu"}
{$template "/datepicker"}
<div class="margin"></div>
<form method="get" action="/settings/authority/nodes/node/logs" class="ui form" autocomplete="off">
<input type="hidden" name="nodeId" :value="nodeId"/>
<div class="ui fields inline">
<div class="ui field">
<input type="text" name="dayFrom" placeholder="开始日期" v-model="dayFrom" value="" style="width:8em" id="day-from-picker"/>
</div>
<div class="ui field">
<input type="text" name="dayTo" placeholder="结束日期" v-model="dayTo" value="" style="width:8em" id="day-to-picker"/>
</div>
<div class="ui field">
<select class="ui dropdown" name="level" v-model="level">
<option value="">[级别]</option>
<option value="error">错误</option>
<option value="warning">警告</option>
<option value="info">信息</option>
</select>
</div>
<div class="ui field">
<input type="text" name="keyword" style="width:10em" v-model="keyword" placeholder="关键词"/>
</div>
<div class="ui field">
<button type="submit" class="ui button">查询</button>
</div>
<div class="ui field" v-if="dayFrom.length > 0 || dayTo.length > 0 || keyword.length > 0 || level.length > 0">
<a :href="'/settings/authority/nodes/node/logs?nodeId=' + nodeId">[清除条件]</a>
</div>
</div>
</form>
<p class="comment" v-if="logs.length == 0">暂时还没有日志。</p>
<table class="ui table selectable" v-if="logs.length > 0">
<thead>
<tr>
</tr>
</thead>
<tr v-for="log in logs">
<td>
<node-log-row :v-log="log" :v-keyword="keyword"></node-log-row>
</td>
</tr>
</table>
<div class="page" v-html="page"></div>

View File

@@ -0,0 +1,6 @@
Tea.context(function () {
this.$delay(function () {
teaweb.datepicker("day-from-picker")
teaweb.datepicker("day-to-picker")
})
})

View File

@@ -2,6 +2,7 @@
<menu-item href="/settings/monitorNodes">节点列表</menu-item> <menu-item href="/settings/monitorNodes">节点列表</menu-item>
<span class="item">|</span> <span class="item">|</span>
<menu-item :href="'/settings/monitorNodes/node?nodeId=' + node.id" code="index">"{{node.name}}"详情</menu-item> <menu-item :href="'/settings/monitorNodes/node?nodeId=' + node.id" code="index">"{{node.name}}"详情</menu-item>
<menu-item :href="'/settings/monitorNodes/node/logs?nodeId=' + node.id" code="log">运行日志</menu-item>
<menu-item :href="'/settings/monitorNodes/node/install?nodeId=' + node.id" code="install">安装节点</menu-item> <menu-item :href="'/settings/monitorNodes/node/install?nodeId=' + node.id" code="install">安装节点</menu-item>
<menu-item :href="'/settings/monitorNodes/node/update?nodeId=' + node.id" code="update">修改节点</menu-item> <menu-item :href="'/settings/monitorNodes/node/update?nodeId=' + node.id" code="update">修改节点</menu-item>
</first-menu> </first-menu>

View File

@@ -0,0 +1,50 @@
{$layout}
{$template "menu"}
{$template "/datepicker"}
<div class="margin"></div>
<form method="get" action="/settings/monitorNodes/node/logs" class="ui form" autocomplete="off">
<input type="hidden" name="nodeId" :value="nodeId"/>
<div class="ui fields inline">
<div class="ui field">
<input type="text" name="dayFrom" placeholder="开始日期" v-model="dayFrom" value="" style="width:8em" id="day-from-picker"/>
</div>
<div class="ui field">
<input type="text" name="dayTo" placeholder="结束日期" v-model="dayTo" value="" style="width:8em" id="day-to-picker"/>
</div>
<div class="ui field">
<select class="ui dropdown" name="level" v-model="level">
<option value="">[级别]</option>
<option value="error">错误</option>
<option value="warning">警告</option>
<option value="info">信息</option>
</select>
</div>
<div class="ui field">
<input type="text" name="keyword" style="width:10em" v-model="keyword" placeholder="关键词"/>
</div>
<div class="ui field">
<button type="submit" class="ui button">查询</button>
</div>
<div class="ui field" v-if="dayFrom.length > 0 || dayTo.length > 0 || keyword.length > 0 || level.length > 0">
<a :href="'/settings/monitorNodes/node/logs?nodeId=' + nodeId">[清除条件]</a>
</div>
</div>
</form>
<p class="comment" v-if="logs.length == 0">暂时还没有日志。</p>
<table class="ui table selectable" v-if="logs.length > 0">
<thead>
<tr>
</tr>
</thead>
<tr v-for="log in logs">
<td>
<node-log-row :v-log="log" :v-keyword="keyword"></node-log-row>
</td>
</tr>
</table>
<div class="page" v-html="page"></div>

View File

@@ -0,0 +1,6 @@
Tea.context(function () {
this.$delay(function () {
teaweb.datepicker("day-from-picker")
teaweb.datepicker("day-to-picker")
})
})

View File

@@ -2,6 +2,7 @@
<menu-item href="/settings/userNodes">节点列表</menu-item> <menu-item href="/settings/userNodes">节点列表</menu-item>
<span class="item">|</span> <span class="item">|</span>
<menu-item :href="'/settings/userNodes/node?nodeId=' + node.id" code="index">"{{node.name}}"详情</menu-item> <menu-item :href="'/settings/userNodes/node?nodeId=' + node.id" code="index">"{{node.name}}"详情</menu-item>
<menu-item :href="'/settings/userNodes/node/logs?nodeId=' + node.id" code="log">运行日志</menu-item>
<menu-item :href="'/settings/userNodes/node/install?nodeId=' + node.id" code="install">安装节点</menu-item> <menu-item :href="'/settings/userNodes/node/install?nodeId=' + node.id" code="install">安装节点</menu-item>
<menu-item :href="'/settings/userNodes/node/update?nodeId=' + node.id" code="update">修改节点</menu-item> <menu-item :href="'/settings/userNodes/node/update?nodeId=' + node.id" code="update">修改节点</menu-item>
</first-menu> </first-menu>

View File

@@ -0,0 +1,50 @@
{$layout}
{$template "menu"}
{$template "/datepicker"}
<div class="margin"></div>
<form method="get" action="/settings/userNodes/node/logs" class="ui form" autocomplete="off">
<input type="hidden" name="nodeId" :value="nodeId"/>
<div class="ui fields inline">
<div class="ui field">
<input type="text" name="dayFrom" placeholder="开始日期" v-model="dayFrom" value="" style="width:8em" id="day-from-picker"/>
</div>
<div class="ui field">
<input type="text" name="dayTo" placeholder="结束日期" v-model="dayTo" value="" style="width:8em" id="day-to-picker"/>
</div>
<div class="ui field">
<select class="ui dropdown" name="level" v-model="level">
<option value="">[级别]</option>
<option value="error">错误</option>
<option value="warning">警告</option>
<option value="info">信息</option>
</select>
</div>
<div class="ui field">
<input type="text" name="keyword" style="width:10em" v-model="keyword" placeholder="关键词"/>
</div>
<div class="ui field">
<button type="submit" class="ui button">查询</button>
</div>
<div class="ui field" v-if="dayFrom.length > 0 || dayTo.length > 0 || keyword.length > 0 || level.length > 0">
<a :href="'/settings/userNodes/node/logs?nodeId=' + nodeId">[清除条件]</a>
</div>
</div>
</form>
<p class="comment" v-if="logs.length == 0">暂时还没有日志。</p>
<table class="ui table selectable" v-if="logs.length > 0">
<thead>
<tr>
</tr>
</thead>
<tr v-for="log in logs">
<td>
<node-log-row :v-log="log" :v-keyword="keyword"></node-log-row>
</td>
</tr>
</table>
<div class="page" v-html="page"></div>

View File

@@ -0,0 +1,6 @@
Tea.context(function () {
this.$delay(function () {
teaweb.datepicker("day-from-picker")
teaweb.datepicker("day-to-picker")
})
})