Skip to content

Commit 2816819

Browse files
committed
feat: read sites access log and error log
1 parent ddaf3e8 commit 2816819

File tree

5 files changed

+147
-10
lines changed

5 files changed

+147
-10
lines changed

frontend/src/routes/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ export const routes = [
102102
path: 'error',
103103
name: () => $gettext('Error Logs'),
104104
component: () => import('@/views/nginx_log/NginxLog.vue'),
105+
}, {
106+
path: 'site',
107+
name: () => $gettext('Site Logs'),
108+
component: () => import('@/views/nginx_log/NginxLog.vue'),
109+
meta: {
110+
hiddenInSidebar: true
111+
},
105112
}]
106113
},
107114
{
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<script setup lang="ts">
2+
import {FileTextOutlined, FileExclamationOutlined} from '@ant-design/icons-vue'
3+
import {computed, ref} from 'vue'
4+
import {useRouter} from 'vue-router'
5+
6+
const props = defineProps(['ngx_config', 'current_server_idx', 'name'])
7+
8+
const accessIdx = ref()
9+
const errorIdx = ref()
10+
11+
const hasAccessLog = computed(() => {
12+
let flag = false
13+
props.ngx_config.servers[props.current_server_idx].directives.forEach((v: any, k: any) => {
14+
if (v.directive === 'access_log') {
15+
flag = true
16+
accessIdx.value = k
17+
return
18+
}
19+
})
20+
return flag
21+
})
22+
23+
const hasErrorLog = computed(() => {
24+
let flag = false
25+
props.ngx_config.servers[props.current_server_idx].directives.forEach((v: any, k: any) => {
26+
if (v.directive === 'error_log') {
27+
flag = true
28+
errorIdx.value = k
29+
return
30+
}
31+
})
32+
return flag
33+
})
34+
35+
const router = useRouter()
36+
37+
function on_click_access_log() {
38+
router.push({
39+
path: '/nginx_log/site',
40+
query: {
41+
server_idx: props.current_server_idx,
42+
directive_idx: accessIdx.value,
43+
conf_name: props.name
44+
}
45+
})
46+
}
47+
48+
function on_click_error_log() {
49+
router.push({
50+
path: '/nginx_log/site',
51+
query: {
52+
server_idx: props.current_server_idx,
53+
directive_idx: errorIdx.value,
54+
conf_name: props.name
55+
}
56+
})
57+
}
58+
</script>
59+
60+
<template>
61+
<a-space style="margin-left: -15px;margin-bottom: 5px" v-if="hasAccessLog||hasErrorLog">
62+
<a-button type="link" v-if="hasAccessLog" @click="on_click_access_log">
63+
<FileTextOutlined/>
64+
Access Logs
65+
</a-button>
66+
<a-button type="link" v-if="hasErrorLog" @click="on_click_error_log">
67+
<FileExclamationOutlined/>
68+
Error Logs
69+
</a-button>
70+
</a-space>
71+
</template>
72+
73+
<style lang="less" scoped>
74+
75+
</style>

frontend/src/views/domain/ngx_conf/NgxConfigEditor.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {computed, ref} from 'vue'
55
import {useRoute} from 'vue-router'
66
import {useGettext} from 'vue3-gettext'
77
import Cert from '@/views/domain/cert/Cert.vue'
8+
import LogEntry from '@/views/domain/ngx_conf/LogEntry.vue'
89
910
const {$gettext} = useGettext()
1011
@@ -138,6 +139,11 @@ const autoCertRef = computed({
138139

139140
<a-tabs v-model:activeKey="current_server_index">
140141
<a-tab-pane :tab="'Server '+(k+1)" v-for="(v,k) in props.ngx_config.servers" :key="k">
142+
<log-entry
143+
:ngx_config="props.ngx_config"
144+
:current_server_idx="current_server_index"
145+
:name="name"
146+
/>
141147

142148
<div class="tab-content">
143149
<template v-if="current_support_ssl&&enabled">

frontend/src/views/nginx_log/NginxLog.vue

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
<script setup lang="ts">
22
import {useGettext} from 'vue3-gettext'
33
import ws from '@/lib/websocket'
4-
import {computed, nextTick, onMounted, onUnmounted, reactive, ref, watch} from 'vue'
4+
import {nextTick, onMounted, onUnmounted, reactive, ref, watch} from 'vue'
55
import ReconnectingWebSocket from 'reconnecting-websocket'
6-
import {useRoute} from 'vue-router'
6+
import {useRoute, useRouter} from 'vue-router'
7+
import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
78
89
const {$gettext} = useGettext()
910
@@ -13,17 +14,24 @@ let websocket: ReconnectingWebSocket | WebSocket
1314
const route = useRoute()
1415
1516
function logType() {
16-
return route.path.indexOf('access') > 0 ? 'access' : 'error'
17+
return route.path.indexOf('access') > 0 ? 'access' : route.path.indexOf('error') > 0 ? 'error' : 'site'
1718
}
1819
1920
const control = reactive({
2021
fetch: 'new',
21-
type: logType()
22+
type: logType(),
23+
conf_name: route.query.conf_name,
24+
server_idx: parseInt(route.query.server_idx as string),
25+
directive_idx: parseInt(route.query.directive_idx as string),
2226
})
2327
2428
function openWs() {
2529
websocket = ws('/api/nginx_log')
26-
websocket.send(JSON.stringify(control))
30+
31+
websocket.onopen = () => {
32+
websocket.send(JSON.stringify(control))
33+
}
34+
2735
websocket.onmessage = (m: any) => {
2836
const para = document.createElement('p')
2937
para.appendChild(document.createTextNode(m.data.trim()));
@@ -76,6 +84,8 @@ onUnmounted(() => {
7684
websocket.close()
7785
})
7886
87+
const router = useRouter()
88+
7989
</script>
8090

8191
<template>
@@ -96,6 +106,11 @@ onUnmounted(() => {
96106
<pre class="nginx-log-container" ref="logContainer"></pre>
97107
</a-card>
98108
</a-card>
109+
<footer-tool-bar v-if="control.type==='site'">
110+
<a-button @click="router.go(-1)">
111+
<translate>Back</translate>
112+
</a-button>
113+
</footer-tool-bar>
99114
</template>
100115

101116
<style lang="less">

server/api/nginx_log.go

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package api
22

33
import (
44
"encoding/json"
5+
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
56
"github.com/0xJacky/Nginx-UI/server/settings"
67
"github.com/gin-gonic/gin"
78
"github.com/gorilla/websocket"
@@ -10,11 +11,15 @@ import (
1011
"io"
1112
"log"
1213
"net/http"
14+
"path/filepath"
1315
)
1416

1517
type controlStruct struct {
16-
Fetch string `json:"fetch"`
17-
Type string `json:"type"`
18+
Fetch string `json:"fetch"`
19+
Type string `json:"type"`
20+
ConfName string `json:"conf_name"`
21+
ServerIdx int `json:"server_idx"`
22+
DirectiveIdx int `json:"directive_idx"`
1823
}
1924

2025
func tailNginxLog(ws *websocket.Conn, controlChan chan controlStruct, errChan chan error) {
@@ -33,11 +38,40 @@ func tailNginxLog(ws *websocket.Conn, controlChan chan controlStruct, errChan ch
3338
seek.Offset = 0
3439
seek.Whence = io.SeekEnd
3540
}
41+
var logPath string
42+
switch control.Type {
43+
case "site":
44+
path := filepath.Join(nginx.GetNginxConfPath("sites-available"), control.ConfName)
45+
config, err := nginx.ParseNgxConfig(path)
46+
if err != nil {
47+
errChan <- errors.Wrap(err, "error parsing ngx config")
48+
return
49+
}
50+
51+
if control.ServerIdx >= len(config.Servers) {
52+
errChan <- errors.New("serverIdx out of range")
53+
return
54+
}
55+
if control.DirectiveIdx >= len(config.Servers[control.ServerIdx].Directives) {
56+
errChan <- errors.New("DirectiveIdx out of range")
57+
return
58+
}
59+
directive := config.Servers[control.ServerIdx].Directives[control.DirectiveIdx]
60+
61+
switch directive.Directive {
62+
case "access_log", "error_log":
63+
// ok
64+
default:
65+
errChan <- errors.New("directive.Params neither access_log nor error_log")
66+
return
67+
}
3668

37-
logPath := settings.NginxLogSettings.AccessLogPath
69+
logPath = directive.Params
3870

39-
if control.Type == "error" {
71+
case "error":
4072
logPath = settings.NginxLogSettings.ErrorLogPath
73+
default:
74+
logPath = settings.NginxLogSettings.AccessLogPath
4175
}
4276

4377
// Create a tail
@@ -61,7 +95,6 @@ func tailNginxLog(ws *websocket.Conn, controlChan chan controlStruct, errChan ch
6195
return
6296
}
6397
case control = <-controlChan:
64-
log.Println("control change")
6598
next = true
6699
break
67100
}
@@ -125,6 +158,7 @@ func NginxLog(c *gin.Context) {
125158

126159
if err = <-errChan; err != nil {
127160
log.Println(err)
161+
_ = ws.WriteMessage(websocket.TextMessage, []byte(err.Error()))
128162
return
129163
}
130164
}

0 commit comments

Comments
 (0)