mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 02:15:48 +02:00
feat: read sites access log and error log
This commit is contained in:
parent
ddaf3e8e60
commit
28168197b1
5 changed files with 147 additions and 10 deletions
|
@ -102,6 +102,13 @@ export const routes = [
|
|||
path: 'error',
|
||||
name: () => $gettext('Error Logs'),
|
||||
component: () => import('@/views/nginx_log/NginxLog.vue'),
|
||||
}, {
|
||||
path: 'site',
|
||||
name: () => $gettext('Site Logs'),
|
||||
component: () => import('@/views/nginx_log/NginxLog.vue'),
|
||||
meta: {
|
||||
hiddenInSidebar: true
|
||||
},
|
||||
}]
|
||||
},
|
||||
{
|
||||
|
|
75
frontend/src/views/domain/ngx_conf/LogEntry.vue
Normal file
75
frontend/src/views/domain/ngx_conf/LogEntry.vue
Normal file
|
@ -0,0 +1,75 @@
|
|||
<script setup lang="ts">
|
||||
import {FileTextOutlined, FileExclamationOutlined} from '@ant-design/icons-vue'
|
||||
import {computed, ref} from 'vue'
|
||||
import {useRouter} from 'vue-router'
|
||||
|
||||
const props = defineProps(['ngx_config', 'current_server_idx', 'name'])
|
||||
|
||||
const accessIdx = ref()
|
||||
const errorIdx = ref()
|
||||
|
||||
const hasAccessLog = computed(() => {
|
||||
let flag = false
|
||||
props.ngx_config.servers[props.current_server_idx].directives.forEach((v: any, k: any) => {
|
||||
if (v.directive === 'access_log') {
|
||||
flag = true
|
||||
accessIdx.value = k
|
||||
return
|
||||
}
|
||||
})
|
||||
return flag
|
||||
})
|
||||
|
||||
const hasErrorLog = computed(() => {
|
||||
let flag = false
|
||||
props.ngx_config.servers[props.current_server_idx].directives.forEach((v: any, k: any) => {
|
||||
if (v.directive === 'error_log') {
|
||||
flag = true
|
||||
errorIdx.value = k
|
||||
return
|
||||
}
|
||||
})
|
||||
return flag
|
||||
})
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
function on_click_access_log() {
|
||||
router.push({
|
||||
path: '/nginx_log/site',
|
||||
query: {
|
||||
server_idx: props.current_server_idx,
|
||||
directive_idx: accessIdx.value,
|
||||
conf_name: props.name
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function on_click_error_log() {
|
||||
router.push({
|
||||
path: '/nginx_log/site',
|
||||
query: {
|
||||
server_idx: props.current_server_idx,
|
||||
directive_idx: errorIdx.value,
|
||||
conf_name: props.name
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-space style="margin-left: -15px;margin-bottom: 5px" v-if="hasAccessLog||hasErrorLog">
|
||||
<a-button type="link" v-if="hasAccessLog" @click="on_click_access_log">
|
||||
<FileTextOutlined/>
|
||||
Access Logs
|
||||
</a-button>
|
||||
<a-button type="link" v-if="hasErrorLog" @click="on_click_error_log">
|
||||
<FileExclamationOutlined/>
|
||||
Error Logs
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
|
@ -5,6 +5,7 @@ import {computed, ref} from 'vue'
|
|||
import {useRoute} from 'vue-router'
|
||||
import {useGettext} from 'vue3-gettext'
|
||||
import Cert from '@/views/domain/cert/Cert.vue'
|
||||
import LogEntry from '@/views/domain/ngx_conf/LogEntry.vue'
|
||||
|
||||
const {$gettext} = useGettext()
|
||||
|
||||
|
@ -138,6 +139,11 @@ const autoCertRef = computed({
|
|||
|
||||
<a-tabs v-model:activeKey="current_server_index">
|
||||
<a-tab-pane :tab="'Server '+(k+1)" v-for="(v,k) in props.ngx_config.servers" :key="k">
|
||||
<log-entry
|
||||
:ngx_config="props.ngx_config"
|
||||
:current_server_idx="current_server_index"
|
||||
:name="name"
|
||||
/>
|
||||
|
||||
<div class="tab-content">
|
||||
<template v-if="current_support_ssl&&enabled">
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<script setup lang="ts">
|
||||
import {useGettext} from 'vue3-gettext'
|
||||
import ws from '@/lib/websocket'
|
||||
import {computed, nextTick, onMounted, onUnmounted, reactive, ref, watch} from 'vue'
|
||||
import {nextTick, onMounted, onUnmounted, reactive, ref, watch} from 'vue'
|
||||
import ReconnectingWebSocket from 'reconnecting-websocket'
|
||||
import {useRoute} from 'vue-router'
|
||||
import {useRoute, useRouter} from 'vue-router'
|
||||
import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
|
||||
|
||||
const {$gettext} = useGettext()
|
||||
|
||||
|
@ -13,17 +14,24 @@ let websocket: ReconnectingWebSocket | WebSocket
|
|||
const route = useRoute()
|
||||
|
||||
function logType() {
|
||||
return route.path.indexOf('access') > 0 ? 'access' : 'error'
|
||||
return route.path.indexOf('access') > 0 ? 'access' : route.path.indexOf('error') > 0 ? 'error' : 'site'
|
||||
}
|
||||
|
||||
const control = reactive({
|
||||
fetch: 'new',
|
||||
type: logType()
|
||||
type: logType(),
|
||||
conf_name: route.query.conf_name,
|
||||
server_idx: parseInt(route.query.server_idx as string),
|
||||
directive_idx: parseInt(route.query.directive_idx as string),
|
||||
})
|
||||
|
||||
function openWs() {
|
||||
websocket = ws('/api/nginx_log')
|
||||
|
||||
websocket.onopen = () => {
|
||||
websocket.send(JSON.stringify(control))
|
||||
}
|
||||
|
||||
websocket.onmessage = (m: any) => {
|
||||
const para = document.createElement('p')
|
||||
para.appendChild(document.createTextNode(m.data.trim()));
|
||||
|
@ -76,6 +84,8 @@ onUnmounted(() => {
|
|||
websocket.close()
|
||||
})
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -96,6 +106,11 @@ onUnmounted(() => {
|
|||
<pre class="nginx-log-container" ref="logContainer"></pre>
|
||||
</a-card>
|
||||
</a-card>
|
||||
<footer-tool-bar v-if="control.type==='site'">
|
||||
<a-button @click="router.go(-1)">
|
||||
<translate>Back</translate>
|
||||
</a-button>
|
||||
</footer-tool-bar>
|
||||
</template>
|
||||
|
||||
<style lang="less">
|
||||
|
|
|
@ -2,6 +2,7 @@ package api
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
|
@ -10,11 +11,15 @@ import (
|
|||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type controlStruct struct {
|
||||
Fetch string `json:"fetch"`
|
||||
Type string `json:"type"`
|
||||
ConfName string `json:"conf_name"`
|
||||
ServerIdx int `json:"server_idx"`
|
||||
DirectiveIdx int `json:"directive_idx"`
|
||||
}
|
||||
|
||||
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
|
|||
seek.Offset = 0
|
||||
seek.Whence = io.SeekEnd
|
||||
}
|
||||
var logPath string
|
||||
switch control.Type {
|
||||
case "site":
|
||||
path := filepath.Join(nginx.GetNginxConfPath("sites-available"), control.ConfName)
|
||||
config, err := nginx.ParseNgxConfig(path)
|
||||
if err != nil {
|
||||
errChan <- errors.Wrap(err, "error parsing ngx config")
|
||||
return
|
||||
}
|
||||
|
||||
logPath := settings.NginxLogSettings.AccessLogPath
|
||||
if control.ServerIdx >= len(config.Servers) {
|
||||
errChan <- errors.New("serverIdx out of range")
|
||||
return
|
||||
}
|
||||
if control.DirectiveIdx >= len(config.Servers[control.ServerIdx].Directives) {
|
||||
errChan <- errors.New("DirectiveIdx out of range")
|
||||
return
|
||||
}
|
||||
directive := config.Servers[control.ServerIdx].Directives[control.DirectiveIdx]
|
||||
|
||||
if control.Type == "error" {
|
||||
switch directive.Directive {
|
||||
case "access_log", "error_log":
|
||||
// ok
|
||||
default:
|
||||
errChan <- errors.New("directive.Params neither access_log nor error_log")
|
||||
return
|
||||
}
|
||||
|
||||
logPath = directive.Params
|
||||
|
||||
case "error":
|
||||
logPath = settings.NginxLogSettings.ErrorLogPath
|
||||
default:
|
||||
logPath = settings.NginxLogSettings.AccessLogPath
|
||||
}
|
||||
|
||||
// Create a tail
|
||||
|
@ -61,7 +95,6 @@ func tailNginxLog(ws *websocket.Conn, controlChan chan controlStruct, errChan ch
|
|||
return
|
||||
}
|
||||
case control = <-controlChan:
|
||||
log.Println("control change")
|
||||
next = true
|
||||
break
|
||||
}
|
||||
|
@ -125,6 +158,7 @@ func NginxLog(c *gin.Context) {
|
|||
|
||||
if err = <-errChan; err != nil {
|
||||
log.Println(err)
|
||||
_ = ws.WriteMessage(websocket.TextMessage, []byte(err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue