Pārlūkot izejas kodu

feat: online read access log and error log

0xJacky 2 gadi atpakaļ
vecāks
revīzija
fea0bc727f

+ 1 - 0
README-zh_CN.md

@@ -77,6 +77,7 @@ Nginx 网络管理界面,由  [0xJacky](https://jackyu.cn/) 与 [Hintay](https
 - 在线查看服务器 CPU、内存、系统负载、磁盘使用率等指标
 - 一键申请和自动续签 Let's encrypt 证书
 - 在线编辑 Nginx 配置文件,编辑器支持 Nginx 配置语法高亮
+- 在线查看 Nginx 日志
 - 使用 Go 和 Vue 开发,发行版本为单个可执行的二进制文件
 - 保存配置后自动测试配置文件并重载 Nginx
 - 基于网页浏览器的高级命令行终端

+ 1 - 0
README-zh_TW.md

@@ -79,6 +79,7 @@ Nginx 網路管理介面,由  [0xJacky](https://jackyu.cn/) 與 [Hintay](https
 - 線上檢視伺服器 CPU、記憶體、系統負載、磁碟使用率等指標
 - 一鍵申請和自動續簽 Let's encrypt 憑證
 - 線上編輯 Nginx 配置檔案,編輯器支援 Nginx 配置語法突顯
+- 線上查看 Nginx 日誌
 - 使用 Go 和 Vue 開發,發行版本為單個可執行檔案
 - 保存配置後自動測試配置檔案並重載 Nginx
 - 基於網頁瀏覽器的高級命令行終端

+ 1 - 0
README.md

@@ -75,6 +75,7 @@ URL:[https://nginxui.jackyu.cn](https://nginxui.jackyu.cn)
 - Online view of server CPU, Memory, Load Average, Disk Usage and other indicators.
 - One-click deployment and automatic renewal Let's Encrypt certificates.
 - Online editing websites configurations with our self-designed **NgxConfigEditor** which is a user-friendly block editor or **Ace Code Editor** which support highlight nginx configuration syntax.
+- Online view Nginx logs
 - Written in Go and Vue, distribution is a single executable binary.
 - Automatically test configuration file and reload nginx after saving configuration.
 - Web Terminal

+ 2 - 2
build.sh

@@ -4,5 +4,5 @@ CGO_ENABLED=1 GOOS=linux CC=x86_64-unknown-linux-gnu-gcc \
     "-X 'github.com/0xJacky/Nginx-UI/server/settings.buildTime=$(date +%s)'" -o nginx-ui -v main.go
 
 docker build -t nginx-ui .
-docker tag nginx-ui uozi/nginx-ui
-docker push uozi/nginx-ui
+# docker tag nginx-ui uozi/nginx-ui
+# docker push uozi/nginx-ui

+ 60 - 27
frontend/src/language/en/app.po

@@ -9,10 +9,14 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/routes/index.ts:92
+#: src/routes/index.ts:116
 msgid "About"
 msgstr "About"
 
+#: src/routes/index.ts:99
+msgid "Access Logs"
+msgstr ""
+
 #: src/views/config/Config.vue:24 src/views/domain/DomainList.vue:42
 #: src/views/user/User.vue:42
 msgid "Action"
@@ -29,12 +33,12 @@ msgstr ""
 msgid "Add Directive Below"
 msgstr "Add Directive Below"
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:31
-#: src/views/domain/ngx_conf/LocationEditor.vue:46
+#: src/views/domain/ngx_conf/LocationEditor.vue:33
+#: src/views/domain/ngx_conf/LocationEditor.vue:48
 msgid "Add Location"
 msgstr "Add Location"
 
-#: src/routes/index.ts:54 src/views/domain/DomainAdd.vue:2
+#: src/routes/index.ts:55 src/views/domain/DomainAdd.vue:2
 msgid "Add Site"
 msgstr "Add Site"
 
@@ -42,6 +46,10 @@ msgstr "Add Site"
 msgid "Advance Mode"
 msgstr "Advance Mode"
 
+#: src/views/nginx_log/NginxLog.vue:100
+msgid "All logs"
+msgstr ""
+
 #: src/components/StdDataDisplay/StdTable.vue:41
 #: src/views/domain/DomainList.vue:27
 #, fuzzy
@@ -52,11 +60,15 @@ msgstr "Are you sure you want to remove this directive?"
 msgid "Are you sure you want to remove this directive?"
 msgstr "Are you sure you want to remove this directive?"
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:17
+#: src/views/domain/ngx_conf/LocationEditor.vue:9
 #, fuzzy
 msgid "Are you sure you want to remove this location?"
 msgstr "Are you sure you want to remove this directive?"
 
+#: src/views/nginx_log/NginxLog.vue:4
+msgid "Auto Refresh"
+msgstr ""
+
 #: src/views/domain/cert/IssueCert.vue:78
 msgid "Auto-renewal disabled for %{name}"
 msgstr "Auto-renewal disabled for %{name}"
@@ -65,7 +77,7 @@ msgstr "Auto-renewal disabled for %{name}"
 msgid "Auto-renewal enabled for %{name}"
 msgstr "Auto-renewal enabled for %{name}"
 
-#: src/views/domain/DomainEdit.vue:178
+#: src/views/domain/DomainEdit.vue:178 src/views/nginx_log/NginxLog.vue:115
 msgid "Back"
 msgstr "Back"
 
@@ -104,9 +116,9 @@ msgid "Certificate Status"
 msgstr "Certificate Status"
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29
-#: src/views/domain/ngx_conf/LocationEditor.vue:33
-#: src/views/domain/ngx_conf/LocationEditor.vue:7
-#: src/views/domain/ngx_conf/NgxConfigEditor.vue:156
+#: src/views/domain/ngx_conf/LocationEditor.vue:21
+#: src/views/domain/ngx_conf/LocationEditor.vue:35
+#: src/views/domain/ngx_conf/NgxConfigEditor.vue:161
 msgid "Comments"
 msgstr "Comments"
 
@@ -122,8 +134,8 @@ msgstr "Configurations"
 msgid "Configure SSL"
 msgstr "Configure SSL"
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:13
-#: src/views/domain/ngx_conf/LocationEditor.vue:39
+#: src/views/domain/ngx_conf/LocationEditor.vue:27
+#: src/views/domain/ngx_conf/LocationEditor.vue:41
 msgid "Content"
 msgstr "Content"
 
@@ -147,7 +159,7 @@ msgstr "Created at"
 msgid "Creating client facilitates communication with the CA server"
 msgstr ""
 
-#: src/routes/index.ts:26
+#: src/routes/index.ts:27
 msgid "Dashboard"
 msgstr "Dashboard"
 
@@ -205,11 +217,11 @@ msgstr "Domain Config Created Successfully"
 msgid "Edit %{n}"
 msgstr "Edit %{n}"
 
-#: src/routes/index.ts:76 src/views/config/ConfigEdit.vue:2
+#: src/routes/index.ts:77 src/views/config/ConfigEdit.vue:2
 msgid "Edit Configuration"
 msgstr "Edit Configuration"
 
-#: src/routes/index.ts:58
+#: src/routes/index.ts:59
 msgid "Edit Site"
 msgstr "Edit Site"
 
@@ -244,6 +256,10 @@ msgstr "Enabled successfully"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "Encrypt website with Let's Encrypt"
 
+#: src/routes/index.ts:103
+msgid "Error Logs"
+msgstr ""
+
 #: src/views/domain/cert/CertInfo.vue:17
 msgid "Expiration Date: %{date}"
 msgstr "Expiration Date: %{date}"
@@ -260,6 +276,10 @@ msgstr "Failed to enable %{msg}"
 msgid "Failed to get certificate information"
 msgstr ""
 
+#: src/views/nginx_log/NginxLog.vue:7
+msgid "Fetch"
+msgstr ""
+
 #: src/views/other/Error.vue:3 src/views/other/Error.vue:4
 msgid "File Not Found"
 msgstr "File Not Found"
@@ -276,11 +296,11 @@ msgstr ""
 msgid "Getting the certificate, please wait..."
 msgstr "Getting the certificate, please wait..."
 
-#: src/routes/index.ts:19
+#: src/routes/index.ts:20
 msgid "Home"
 msgstr "Home"
 
-#: src/routes/index.ts:102 src/views/other/Install.vue:128
+#: src/routes/index.ts:126 src/views/other/Install.vue:128
 msgid "Install"
 msgstr "Install"
 
@@ -314,7 +334,7 @@ msgstr "Location"
 msgid "Locations"
 msgstr "Locations"
 
-#: src/routes/index.ts:108 src/views/other/Login.vue:103
+#: src/routes/index.ts:132 src/views/other/Login.vue:103
 msgid "Login"
 msgstr "Login"
 
@@ -334,15 +354,15 @@ msgstr ""
 "Make sure you have configured a reverse proxy for .well-known directory to "
 "HTTPChallengePort (default: 9180) before getting the certificate."
 
-#: src/routes/index.ts:67
+#: src/routes/index.ts:68
 msgid "Manage Configs"
 msgstr "Manage Configs"
 
-#: src/routes/index.ts:42 src/views/domain/DomainList.vue:2
+#: src/routes/index.ts:43 src/views/domain/DomainList.vue:2
 msgid "Manage Sites"
 msgstr "Manage Sites"
 
-#: src/routes/index.ts:34 src/views/user/User.vue:2
+#: src/routes/index.ts:35 src/views/user/User.vue:2
 msgid "Manage Users"
 msgstr "Manage Users"
 
@@ -388,18 +408,26 @@ msgstr "Network Total Receive"
 msgid "Network Total Send"
 msgstr "Network Total Send"
 
+#: src/views/nginx_log/NginxLog.vue:103
+msgid "New logs"
+msgstr ""
+
 #: src/views/domain/DomainAdd.vue:137
 msgid "Next"
 msgstr "Next"
 
+#: src/routes/index.ts:93 src/views/nginx_log/NginxLog.vue:2
+msgid "Nginx Log"
+msgstr ""
+
 #: src/components/StdDataDisplay/StdTable.vue:39
 #: src/views/domain/DomainList.vue:25
 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:17
-#: src/views/domain/ngx_conf/LocationEditor.vue:19
+#: src/views/domain/ngx_conf/LocationEditor.vue:11
 msgid "No"
 msgstr "No"
 
-#: src/routes/index.ts:114 src/routes/index.ts:116
+#: src/routes/index.ts:138 src/routes/index.ts:140
 msgid "Not Found"
 msgstr "Not Found"
 
@@ -441,8 +469,8 @@ msgstr "Password"
 msgid "Password (*)"
 msgstr "Password (*)"
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:10
-#: src/views/domain/ngx_conf/LocationEditor.vue:36
+#: src/views/domain/ngx_conf/LocationEditor.vue:24
+#: src/views/domain/ngx_conf/LocationEditor.vue:38
 msgid "Path"
 msgstr "Path"
 
@@ -552,7 +580,12 @@ msgstr "server_name parameters more than one"
 msgid "Single Directive"
 msgstr "Single Directive"
 
-#: src/routes/index.ts:50
+#: src/routes/index.ts:107
+#, fuzzy
+msgid "Site Logs"
+msgstr "Sites List"
+
+#: src/routes/index.ts:51
 msgid "Sites List"
 msgstr "Sites List"
 
@@ -577,7 +610,7 @@ msgstr "Swap"
 msgid "Table"
 msgstr "Enabled"
 
-#: src/routes/index.ts:84 src/views/pty/Terminal.vue:2
+#: src/routes/index.ts:85 src/views/pty/Terminal.vue:2
 msgid "Terminal"
 msgstr "Terminal"
 
@@ -636,7 +669,7 @@ msgid "Writing certificate to disk"
 msgstr ""
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:16
-#: src/views/domain/ngx_conf/LocationEditor.vue:18
+#: src/views/domain/ngx_conf/LocationEditor.vue:10
 msgid "Yes"
 msgstr "Yes"
 

+ 61 - 27
frontend/src/language/messages.pot

@@ -2,10 +2,14 @@ msgid ""
 msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 
-#: src/routes/index.ts:92
+#: src/routes/index.ts:116
 msgid "About"
 msgstr ""
 
+#: src/routes/index.ts:99
+msgid "Access Logs"
+msgstr ""
+
 #: src/views/config/Config.vue:24
 #: src/views/domain/DomainList.vue:42
 #: src/views/user/User.vue:42
@@ -23,12 +27,12 @@ msgstr ""
 msgid "Add Directive Below"
 msgstr ""
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:31
-#: src/views/domain/ngx_conf/LocationEditor.vue:46
+#: src/views/domain/ngx_conf/LocationEditor.vue:33
+#: src/views/domain/ngx_conf/LocationEditor.vue:48
 msgid "Add Location"
 msgstr ""
 
-#: src/routes/index.ts:54
+#: src/routes/index.ts:55
 #: src/views/domain/DomainAdd.vue:2
 msgid "Add Site"
 msgstr ""
@@ -37,6 +41,10 @@ msgstr ""
 msgid "Advance Mode"
 msgstr ""
 
+#: src/views/nginx_log/NginxLog.vue:100
+msgid "All logs"
+msgstr ""
+
 #: src/components/StdDataDisplay/StdTable.vue:41
 #: src/views/domain/DomainList.vue:27
 msgid "Are you sure you want to delete ?"
@@ -46,10 +54,14 @@ msgstr ""
 msgid "Are you sure you want to remove this directive?"
 msgstr ""
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:17
+#: src/views/domain/ngx_conf/LocationEditor.vue:9
 msgid "Are you sure you want to remove this location?"
 msgstr ""
 
+#: src/views/nginx_log/NginxLog.vue:4
+msgid "Auto Refresh"
+msgstr ""
+
 #: src/views/domain/cert/IssueCert.vue:78
 msgid "Auto-renewal disabled for %{name}"
 msgstr ""
@@ -59,6 +71,7 @@ msgid "Auto-renewal enabled for %{name}"
 msgstr ""
 
 #: src/views/domain/DomainEdit.vue:178
+#: src/views/nginx_log/NginxLog.vue:115
 msgid "Back"
 msgstr ""
 
@@ -96,9 +109,9 @@ msgid "Certificate Status"
 msgstr ""
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29
-#: src/views/domain/ngx_conf/LocationEditor.vue:33
-#: src/views/domain/ngx_conf/LocationEditor.vue:7
-#: src/views/domain/ngx_conf/NgxConfigEditor.vue:156
+#: src/views/domain/ngx_conf/LocationEditor.vue:21
+#: src/views/domain/ngx_conf/LocationEditor.vue:35
+#: src/views/domain/ngx_conf/NgxConfigEditor.vue:161
 msgid "Comments"
 msgstr ""
 
@@ -114,8 +127,8 @@ msgstr ""
 msgid "Configure SSL"
 msgstr ""
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:13
-#: src/views/domain/ngx_conf/LocationEditor.vue:39
+#: src/views/domain/ngx_conf/LocationEditor.vue:27
+#: src/views/domain/ngx_conf/LocationEditor.vue:41
 msgid "Content"
 msgstr ""
 
@@ -139,7 +152,7 @@ msgstr ""
 msgid "Creating client facilitates communication with the CA server"
 msgstr ""
 
-#: src/routes/index.ts:26
+#: src/routes/index.ts:27
 msgid "Dashboard"
 msgstr ""
 
@@ -200,12 +213,12 @@ msgstr ""
 msgid "Edit %{n}"
 msgstr ""
 
-#: src/routes/index.ts:76
+#: src/routes/index.ts:77
 #: src/views/config/ConfigEdit.vue:2
 msgid "Edit Configuration"
 msgstr ""
 
-#: src/routes/index.ts:58
+#: src/routes/index.ts:59
 msgid "Edit Site"
 msgstr ""
 
@@ -243,6 +256,10 @@ msgstr ""
 msgid "Encrypt website with Let's Encrypt"
 msgstr ""
 
+#: src/routes/index.ts:103
+msgid "Error Logs"
+msgstr ""
+
 #: src/views/domain/cert/CertInfo.vue:17
 msgid "Expiration Date: %{date}"
 msgstr ""
@@ -261,6 +278,10 @@ msgstr ""
 msgid "Failed to get certificate information"
 msgstr ""
 
+#: src/views/nginx_log/NginxLog.vue:7
+msgid "Fetch"
+msgstr ""
+
 #: src/views/other/Error.vue:3
 #: src/views/other/Error.vue:4
 msgid "File Not Found"
@@ -279,11 +300,11 @@ msgstr ""
 msgid "Getting the certificate, please wait..."
 msgstr ""
 
-#: src/routes/index.ts:19
+#: src/routes/index.ts:20
 msgid "Home"
 msgstr ""
 
-#: src/routes/index.ts:102
+#: src/routes/index.ts:126
 #: src/views/other/Install.vue:128
 msgid "Install"
 msgstr ""
@@ -316,7 +337,7 @@ msgstr ""
 msgid "Locations"
 msgstr ""
 
-#: src/routes/index.ts:108
+#: src/routes/index.ts:132
 #: src/views/other/Login.vue:103
 msgid "Login"
 msgstr ""
@@ -333,16 +354,16 @@ msgstr ""
 msgid "Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate."
 msgstr ""
 
-#: src/routes/index.ts:67
+#: src/routes/index.ts:68
 msgid "Manage Configs"
 msgstr ""
 
-#: src/routes/index.ts:42
+#: src/routes/index.ts:43
 #: src/views/domain/DomainList.vue:2
 msgid "Manage Sites"
 msgstr ""
 
-#: src/routes/index.ts:34
+#: src/routes/index.ts:35
 #: src/views/user/User.vue:2
 msgid "Manage Users"
 msgstr ""
@@ -389,19 +410,28 @@ msgstr ""
 msgid "Network Total Send"
 msgstr ""
 
+#: src/views/nginx_log/NginxLog.vue:103
+msgid "New logs"
+msgstr ""
+
 #: src/views/domain/DomainAdd.vue:137
 msgid "Next"
 msgstr ""
 
+#: src/routes/index.ts:93
+#: src/views/nginx_log/NginxLog.vue:2
+msgid "Nginx Log"
+msgstr ""
+
 #: src/components/StdDataDisplay/StdTable.vue:39
 #: src/views/domain/DomainList.vue:25
 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:17
-#: src/views/domain/ngx_conf/LocationEditor.vue:19
+#: src/views/domain/ngx_conf/LocationEditor.vue:11
 msgid "No"
 msgstr ""
 
-#: src/routes/index.ts:114
-#: src/routes/index.ts:116
+#: src/routes/index.ts:138
+#: src/routes/index.ts:140
 msgid "Not Found"
 msgstr ""
 
@@ -441,8 +471,8 @@ msgstr ""
 msgid "Password (*)"
 msgstr ""
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:10
-#: src/views/domain/ngx_conf/LocationEditor.vue:36
+#: src/views/domain/ngx_conf/LocationEditor.vue:24
+#: src/views/domain/ngx_conf/LocationEditor.vue:38
 msgid "Path"
 msgstr ""
 
@@ -561,7 +591,11 @@ msgstr ""
 msgid "Single Directive"
 msgstr ""
 
-#: src/routes/index.ts:50
+#: src/routes/index.ts:107
+msgid "Site Logs"
+msgstr ""
+
+#: src/routes/index.ts:51
 msgid "Sites List"
 msgstr ""
 
@@ -585,7 +619,7 @@ msgstr ""
 msgid "Table"
 msgstr ""
 
-#: src/routes/index.ts:84
+#: src/routes/index.ts:85
 #: src/views/pty/Terminal.vue:2
 msgid "Terminal"
 msgstr ""
@@ -645,7 +679,7 @@ msgid "Writing certificate to disk"
 msgstr ""
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:16
-#: src/views/domain/ngx_conf/LocationEditor.vue:18
+#: src/views/domain/ngx_conf/LocationEditor.vue:10
 msgid "Yes"
 msgstr ""
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
frontend/src/language/translations.json


BIN
frontend/src/language/zh_CN/app.mo


+ 59 - 27
frontend/src/language/zh_CN/app.po

@@ -12,10 +12,14 @@ msgstr ""
 "Generated-By: easygettext\n"
 "X-Generator: Poedit 3.1.1\n"
 
-#: src/routes/index.ts:92
+#: src/routes/index.ts:116
 msgid "About"
 msgstr "关于"
 
+#: src/routes/index.ts:99
+msgid "Access Logs"
+msgstr "访问日志"
+
 #: src/views/config/Config.vue:24 src/views/domain/DomainList.vue:42
 #: src/views/user/User.vue:42
 msgid "Action"
@@ -32,12 +36,12 @@ msgstr "添加"
 msgid "Add Directive Below"
 msgstr "在下面添加指令"
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:31
-#: src/views/domain/ngx_conf/LocationEditor.vue:46
+#: src/views/domain/ngx_conf/LocationEditor.vue:33
+#: src/views/domain/ngx_conf/LocationEditor.vue:48
 msgid "Add Location"
 msgstr "添加 Location"
 
-#: src/routes/index.ts:54 src/views/domain/DomainAdd.vue:2
+#: src/routes/index.ts:55 src/views/domain/DomainAdd.vue:2
 msgid "Add Site"
 msgstr "添加站点"
 
@@ -45,6 +49,10 @@ msgstr "添加站点"
 msgid "Advance Mode"
 msgstr "高级模式"
 
+#: src/views/nginx_log/NginxLog.vue:100
+msgid "All logs"
+msgstr "所有日志"
+
 #: src/components/StdDataDisplay/StdTable.vue:41
 #: src/views/domain/DomainList.vue:27
 msgid "Are you sure you want to delete ?"
@@ -54,10 +62,14 @@ msgstr "您确定要删除吗?"
 msgid "Are you sure you want to remove this directive?"
 msgstr "您确定要删除这条指令?"
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:17
+#: src/views/domain/ngx_conf/LocationEditor.vue:9
 msgid "Are you sure you want to remove this location?"
 msgstr "您确定要删除这个 Location?"
 
+#: src/views/nginx_log/NginxLog.vue:4
+msgid "Auto Refresh"
+msgstr "自动刷新"
+
 #: src/views/domain/cert/IssueCert.vue:78
 msgid "Auto-renewal disabled for %{name}"
 msgstr "成功关闭 %{name} 自动续签"
@@ -66,7 +78,7 @@ msgstr "成功关闭 %{name} 自动续签"
 msgid "Auto-renewal enabled for %{name}"
 msgstr "成功启用 %{name} 自动续签"
 
-#: src/views/domain/DomainEdit.vue:178
+#: src/views/domain/DomainEdit.vue:178 src/views/nginx_log/NginxLog.vue:115
 msgid "Back"
 msgstr "返回"
 
@@ -104,9 +116,9 @@ msgid "Certificate Status"
 msgstr "证书状态"
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29
-#: src/views/domain/ngx_conf/LocationEditor.vue:33
-#: src/views/domain/ngx_conf/LocationEditor.vue:7
-#: src/views/domain/ngx_conf/NgxConfigEditor.vue:156
+#: src/views/domain/ngx_conf/LocationEditor.vue:21
+#: src/views/domain/ngx_conf/LocationEditor.vue:35
+#: src/views/domain/ngx_conf/NgxConfigEditor.vue:161
 msgid "Comments"
 msgstr "注释"
 
@@ -122,8 +134,8 @@ msgstr "配置"
 msgid "Configure SSL"
 msgstr "配置 SSL"
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:13
-#: src/views/domain/ngx_conf/LocationEditor.vue:39
+#: src/views/domain/ngx_conf/LocationEditor.vue:27
+#: src/views/domain/ngx_conf/LocationEditor.vue:41
 msgid "Content"
 msgstr "内容"
 
@@ -147,7 +159,7 @@ msgstr "创建时间"
 msgid "Creating client facilitates communication with the CA server"
 msgstr "正在创建客户端用于与 CA 服务器通信"
 
-#: src/routes/index.ts:26
+#: src/routes/index.ts:27
 msgid "Dashboard"
 msgstr "仪表盘"
 
@@ -205,11 +217,11 @@ msgstr "域名配置文件创建成功"
 msgid "Edit %{n}"
 msgstr "编辑 %{n}"
 
-#: src/routes/index.ts:76 src/views/config/ConfigEdit.vue:2
+#: src/routes/index.ts:77 src/views/config/ConfigEdit.vue:2
 msgid "Edit Configuration"
 msgstr "编辑配置"
 
-#: src/routes/index.ts:58
+#: src/routes/index.ts:59
 msgid "Edit Site"
 msgstr "编辑站点"
 
@@ -244,6 +256,10 @@ msgstr "启用成功"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "用 Let's Encrypt 对网站进行加密"
 
+#: src/routes/index.ts:103
+msgid "Error Logs"
+msgstr "错误日志"
+
 #: src/views/domain/cert/CertInfo.vue:17
 msgid "Expiration Date: %{date}"
 msgstr "过期时间: %{date}"
@@ -260,6 +276,10 @@ msgstr "启用失败 %{msg}"
 msgid "Failed to get certificate information"
 msgstr "获取证书信息失败"
 
+#: src/views/nginx_log/NginxLog.vue:7
+msgid "Fetch"
+msgstr "日志范围"
+
 #: src/views/other/Error.vue:3 src/views/other/Error.vue:4
 msgid "File Not Found"
 msgstr "未找到文件"
@@ -276,11 +296,11 @@ msgstr "正在生成私钥用于注册账户"
 msgid "Getting the certificate, please wait..."
 msgstr "正在获取证书,请稍等..."
 
-#: src/routes/index.ts:19
+#: src/routes/index.ts:20
 msgid "Home"
 msgstr "首页"
 
-#: src/routes/index.ts:102 src/views/other/Install.vue:128
+#: src/routes/index.ts:126 src/views/other/Install.vue:128
 msgid "Install"
 msgstr "安装"
 
@@ -312,7 +332,7 @@ msgstr "Location"
 msgid "Locations"
 msgstr "Locations"
 
-#: src/routes/index.ts:108 src/views/other/Login.vue:103
+#: src/routes/index.ts:132 src/views/other/Login.vue:103
 msgid "Login"
 msgstr "登录"
 
@@ -332,15 +352,15 @@ msgstr ""
 "在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 "
 "HTTPChallengePort (默认: 9180)"
 
-#: src/routes/index.ts:67
+#: src/routes/index.ts:68
 msgid "Manage Configs"
 msgstr "配置管理"
 
-#: src/routes/index.ts:42 src/views/domain/DomainList.vue:2
+#: src/routes/index.ts:43 src/views/domain/DomainList.vue:2
 msgid "Manage Sites"
 msgstr "网站管理"
 
-#: src/routes/index.ts:34 src/views/user/User.vue:2
+#: src/routes/index.ts:35 src/views/user/User.vue:2
 msgid "Manage Users"
 msgstr "用户管理"
 
@@ -385,18 +405,26 @@ msgstr "下载流量"
 msgid "Network Total Send"
 msgstr "上传流量"
 
+#: src/views/nginx_log/NginxLog.vue:103
+msgid "New logs"
+msgstr "新增日志"
+
 #: src/views/domain/DomainAdd.vue:137
 msgid "Next"
 msgstr "下一步"
 
+#: src/routes/index.ts:93 src/views/nginx_log/NginxLog.vue:2
+msgid "Nginx Log"
+msgstr "Nginx 日志"
+
 #: src/components/StdDataDisplay/StdTable.vue:39
 #: src/views/domain/DomainList.vue:25
 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:17
-#: src/views/domain/ngx_conf/LocationEditor.vue:19
+#: src/views/domain/ngx_conf/LocationEditor.vue:11
 msgid "No"
 msgstr "取消"
 
-#: src/routes/index.ts:114 src/routes/index.ts:116
+#: src/routes/index.ts:138 src/routes/index.ts:140
 msgid "Not Found"
 msgstr "找不到页面"
 
@@ -436,8 +464,8 @@ msgstr "密码"
 msgid "Password (*)"
 msgstr "密码 (*)"
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:10
-#: src/views/domain/ngx_conf/LocationEditor.vue:36
+#: src/views/domain/ngx_conf/LocationEditor.vue:24
+#: src/views/domain/ngx_conf/LocationEditor.vue:38
 msgid "Path"
 msgstr "路径"
 
@@ -545,7 +573,11 @@ msgstr "server_name 指令包含多个参数"
 msgid "Single Directive"
 msgstr "单行指令"
 
-#: src/routes/index.ts:50
+#: src/routes/index.ts:107
+msgid "Site Logs"
+msgstr "站点列表"
+
+#: src/routes/index.ts:51
 msgid "Sites List"
 msgstr "站点列表"
 
@@ -569,7 +601,7 @@ msgstr ""
 msgid "Table"
 msgstr "列表"
 
-#: src/routes/index.ts:84 src/views/pty/Terminal.vue:2
+#: src/routes/index.ts:85 src/views/pty/Terminal.vue:2
 msgid "Terminal"
 msgstr "终端"
 
@@ -627,7 +659,7 @@ msgid "Writing certificate to disk"
 msgstr "正在将证书写入磁盘"
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:16
-#: src/views/domain/ngx_conf/LocationEditor.vue:18
+#: src/views/domain/ngx_conf/LocationEditor.vue:10
 msgid "Yes"
 msgstr "是的"
 

+ 60 - 27
frontend/src/language/zh_TW/app.po

@@ -13,10 +13,14 @@ msgstr ""
 "Generated-By: easygettext\n"
 "X-Generator: Poedit 2.2\n"
 
-#: src/routes/index.ts:92
+#: src/routes/index.ts:116
 msgid "About"
 msgstr "關於"
 
+#: src/routes/index.ts:99
+msgid "Access Logs"
+msgstr ""
+
 #: src/views/config/Config.vue:24 src/views/domain/DomainList.vue:42
 #: src/views/user/User.vue:42
 msgid "Action"
@@ -33,12 +37,12 @@ msgstr ""
 msgid "Add Directive Below"
 msgstr "在下面新增指令"
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:31
-#: src/views/domain/ngx_conf/LocationEditor.vue:46
+#: src/views/domain/ngx_conf/LocationEditor.vue:33
+#: src/views/domain/ngx_conf/LocationEditor.vue:48
 msgid "Add Location"
 msgstr "新增 Location"
 
-#: src/routes/index.ts:54 src/views/domain/DomainAdd.vue:2
+#: src/routes/index.ts:55 src/views/domain/DomainAdd.vue:2
 msgid "Add Site"
 msgstr "新增站點"
 
@@ -46,6 +50,10 @@ msgstr "新增站點"
 msgid "Advance Mode"
 msgstr "高階模式"
 
+#: src/views/nginx_log/NginxLog.vue:100
+msgid "All logs"
+msgstr ""
+
 #: src/components/StdDataDisplay/StdTable.vue:41
 #: src/views/domain/DomainList.vue:27
 #, fuzzy
@@ -56,11 +64,15 @@ msgstr "您确定要删除?"
 msgid "Are you sure you want to remove this directive?"
 msgstr "您確定要刪除這條指令?"
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:17
+#: src/views/domain/ngx_conf/LocationEditor.vue:9
 #, fuzzy
 msgid "Are you sure you want to remove this location?"
 msgstr "您確定要刪除這條指令?"
 
+#: src/views/nginx_log/NginxLog.vue:4
+msgid "Auto Refresh"
+msgstr ""
+
 #: src/views/domain/cert/IssueCert.vue:78
 msgid "Auto-renewal disabled for %{name}"
 msgstr "已關閉 %{name} 自動續簽"
@@ -69,7 +81,7 @@ msgstr "已關閉 %{name} 自動續簽"
 msgid "Auto-renewal enabled for %{name}"
 msgstr "已啟用 %{name} 自動續簽"
 
-#: src/views/domain/DomainEdit.vue:178
+#: src/views/domain/DomainEdit.vue:178 src/views/nginx_log/NginxLog.vue:115
 msgid "Back"
 msgstr "返回"
 
@@ -108,9 +120,9 @@ msgid "Certificate Status"
 msgstr "憑證狀態"
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:29
-#: src/views/domain/ngx_conf/LocationEditor.vue:33
-#: src/views/domain/ngx_conf/LocationEditor.vue:7
-#: src/views/domain/ngx_conf/NgxConfigEditor.vue:156
+#: src/views/domain/ngx_conf/LocationEditor.vue:21
+#: src/views/domain/ngx_conf/LocationEditor.vue:35
+#: src/views/domain/ngx_conf/NgxConfigEditor.vue:161
 msgid "Comments"
 msgstr "註釋"
 
@@ -126,8 +138,8 @@ msgstr "配置"
 msgid "Configure SSL"
 msgstr "配置 SSL"
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:13
-#: src/views/domain/ngx_conf/LocationEditor.vue:39
+#: src/views/domain/ngx_conf/LocationEditor.vue:27
+#: src/views/domain/ngx_conf/LocationEditor.vue:41
 msgid "Content"
 msgstr "內容"
 
@@ -151,7 +163,7 @@ msgstr "建立時間"
 msgid "Creating client facilitates communication with the CA server"
 msgstr ""
 
-#: src/routes/index.ts:26
+#: src/routes/index.ts:27
 msgid "Dashboard"
 msgstr "儀表盤"
 
@@ -210,11 +222,11 @@ msgstr "域名配置文件創建成功"
 msgid "Edit %{n}"
 msgstr "編輯 %{n}"
 
-#: src/routes/index.ts:76 src/views/config/ConfigEdit.vue:2
+#: src/routes/index.ts:77 src/views/config/ConfigEdit.vue:2
 msgid "Edit Configuration"
 msgstr "編輯配置"
 
-#: src/routes/index.ts:58
+#: src/routes/index.ts:59
 msgid "Edit Site"
 msgstr "編輯站點"
 
@@ -249,6 +261,10 @@ msgstr "啟用成功"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "用 Let's Encrypt 對網站進行加密"
 
+#: src/routes/index.ts:103
+msgid "Error Logs"
+msgstr ""
+
 #: src/views/domain/cert/CertInfo.vue:17
 msgid "Expiration Date: %{date}"
 msgstr "過期時間: %{date}"
@@ -265,6 +281,10 @@ msgstr "啟用失敗 %{msg}"
 msgid "Failed to get certificate information"
 msgstr ""
 
+#: src/views/nginx_log/NginxLog.vue:7
+msgid "Fetch"
+msgstr ""
+
 #: src/views/other/Error.vue:3 src/views/other/Error.vue:4
 msgid "File Not Found"
 msgstr "未找到檔案"
@@ -281,11 +301,11 @@ msgstr ""
 msgid "Getting the certificate, please wait..."
 msgstr "正在獲取憑證,請稍等..."
 
-#: src/routes/index.ts:19
+#: src/routes/index.ts:20
 msgid "Home"
 msgstr "首頁"
 
-#: src/routes/index.ts:102 src/views/other/Install.vue:128
+#: src/routes/index.ts:126 src/views/other/Install.vue:128
 msgid "Install"
 msgstr "安裝"
 
@@ -319,7 +339,7 @@ msgstr "Location"
 msgid "Locations"
 msgstr "Locations"
 
-#: src/routes/index.ts:108 src/views/other/Login.vue:103
+#: src/routes/index.ts:132 src/views/other/Login.vue:103
 msgid "Login"
 msgstr "登入"
 
@@ -340,15 +360,15 @@ msgstr ""
 "在獲取憑證前,請確保配置檔案中已將 .well-known 目錄反向代理到 "
 "HTTPChallengePort (預設: 9180)"
 
-#: src/routes/index.ts:67
+#: src/routes/index.ts:68
 msgid "Manage Configs"
 msgstr "配置管理"
 
-#: src/routes/index.ts:42 src/views/domain/DomainList.vue:2
+#: src/routes/index.ts:43 src/views/domain/DomainList.vue:2
 msgid "Manage Sites"
 msgstr "網站管理"
 
-#: src/routes/index.ts:34 src/views/user/User.vue:2
+#: src/routes/index.ts:35 src/views/user/User.vue:2
 msgid "Manage Users"
 msgstr "使用者管理"
 
@@ -394,18 +414,26 @@ msgstr "下載流量"
 msgid "Network Total Send"
 msgstr "上傳流量"
 
+#: src/views/nginx_log/NginxLog.vue:103
+msgid "New logs"
+msgstr ""
+
 #: src/views/domain/DomainAdd.vue:137
 msgid "Next"
 msgstr "下一步"
 
+#: src/routes/index.ts:93 src/views/nginx_log/NginxLog.vue:2
+msgid "Nginx Log"
+msgstr ""
+
 #: src/components/StdDataDisplay/StdTable.vue:39
 #: src/views/domain/DomainList.vue:25
 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:17
-#: src/views/domain/ngx_conf/LocationEditor.vue:19
+#: src/views/domain/ngx_conf/LocationEditor.vue:11
 msgid "No"
 msgstr "取消"
 
-#: src/routes/index.ts:114 src/routes/index.ts:116
+#: src/routes/index.ts:138 src/routes/index.ts:140
 msgid "Not Found"
 msgstr "找不到頁面"
 
@@ -446,8 +474,8 @@ msgstr "密碼"
 msgid "Password (*)"
 msgstr "密碼 (*)"
 
-#: src/views/domain/ngx_conf/LocationEditor.vue:10
-#: src/views/domain/ngx_conf/LocationEditor.vue:36
+#: src/views/domain/ngx_conf/LocationEditor.vue:24
+#: src/views/domain/ngx_conf/LocationEditor.vue:38
 msgid "Path"
 msgstr "路徑"
 
@@ -557,7 +585,12 @@ msgstr "server_name 指令包含多個參數"
 msgid "Single Directive"
 msgstr "單行指令"
 
-#: src/routes/index.ts:50
+#: src/routes/index.ts:107
+#, fuzzy
+msgid "Site Logs"
+msgstr "站點列表"
+
+#: src/routes/index.ts:51
 msgid "Sites List"
 msgstr "站點列表"
 
@@ -582,7 +615,7 @@ msgstr "交換空間"
 msgid "Table"
 msgstr "啟用"
 
-#: src/routes/index.ts:84 src/views/pty/Terminal.vue:2
+#: src/routes/index.ts:85 src/views/pty/Terminal.vue:2
 msgid "Terminal"
 msgstr "終端"
 
@@ -642,7 +675,7 @@ msgid "Writing certificate to disk"
 msgstr ""
 
 #: src/views/domain/ngx_conf/directive/DirectiveEditor.vue:16
-#: src/views/domain/ngx_conf/LocationEditor.vue:18
+#: src/views/domain/ngx_conf/LocationEditor.vue:10
 msgid "Yes"
 msgstr "是的"
 

+ 1 - 1
frontend/src/version.json

@@ -1 +1 @@
-{"version":"1.5.0","build_id":45,"total_build":115}
+{"version":"1.5.0","build_id":46,"total_build":116}

+ 2 - 2
frontend/src/views/domain/ngx_conf/LogEntry.vue

@@ -61,11 +61,11 @@ function on_click_error_log() {
     <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
+            <translate>Access Logs</translate>
         </a-button>
         <a-button type="link" v-if="hasErrorLog" @click="on_click_error_log">
             <FileExclamationOutlined/>
-            Error Logs
+            <translate>Error Logs</translate>
         </a-button>
     </a-space>
 </template>

+ 16 - 2
frontend/src/views/domain/ngx_conf/NgxConfigEditor.vue

@@ -1,8 +1,8 @@
 <script setup lang="ts">
 import DirectiveEditor from '@/views/domain/ngx_conf/directive/DirectiveEditor.vue'
 import LocationEditor from '@/views/domain/ngx_conf/LocationEditor.vue'
-import {computed, ref} from 'vue'
-import {useRoute} from 'vue-router'
+import {computed, onMounted, ref, watch} from 'vue'
+import {useRoute, useRouter} 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'
@@ -129,6 +129,20 @@ const autoCertRef = computed({
     }
 })
 
+onMounted(() => {
+    current_server_index.value = parseInt((route.query?.server_idx ?? 0) as string)
+})
+
+const router = useRouter()
+
+watch(current_server_index, () => {
+    router.push({
+        query: {
+            server_idx: current_server_index.value.toString()
+        }
+    })
+})
+
 </script>
 
 <template>

+ 6 - 2
frontend/src/views/nginx_log/NginxLog.vue

@@ -96,8 +96,12 @@ const router = useRouter()
             </a-form-item>
             <a-form-item :label="$gettext('Fetch')">
                 <a-select v-model:value="control.fetch" style="max-width: 200px">
-                    <a-select-option value="all">All logs</a-select-option>
-                    <a-select-option value="new">New logs</a-select-option>
+                    <a-select-option value="all">
+                        <translate>All logs</translate>
+                    </a-select-option>
+                    <a-select-option value="new">
+                        <translate>New logs</translate>
+                    </a-select-option>
                 </a-select>
             </a-form-item>
         </a-form>

+ 1 - 1
frontend/version.json

@@ -1 +1 @@
-{"version":"1.5.0","build_id":45,"total_build":115}
+{"version":"1.5.0","build_id":46,"total_build":116}

+ 4 - 0
resources/demo/app.ini

@@ -5,3 +5,7 @@ JwtSecret = 2E1CE615-BB15-44F5-B5BE-6B5DA3581D0F
 Email = test@jackyu.cn
 HTTPChallengePort = 9180
 StartCmd = bash
+
+[nginx_log]
+AccessLogPath = /var/log/nginx/access.local.log
+ErrorLogPath = /var/log/nginx/error.local.log

+ 4 - 1
resources/demo/ojbk.me

@@ -3,6 +3,9 @@ server {
 	listen [::]:80;
 	server_name ojbk.me;
 
+	access_log /var/log/nginx/ojbk.me.log;
+	error_log /var/log/nginx/ojbk.me.error.log;
+
 	location /.well-known/acme-challenge {
 		proxy_set_header Host $host;
 		proxy_set_header X-Real_IP $remote_addr;
@@ -10,4 +13,4 @@ server {
 		proxy_pass http://127.0.0.1:9180;
 	}
 
-}
+}

+ 2 - 0
resources/docker/nginx.conf

@@ -2,6 +2,7 @@ user  nginx;
 worker_processes  auto;
 
 error_log  /var/log/nginx/error.log notice;
+error_log  /var/log/nginx/error.local.log notice;
 pid        /var/run/nginx.pid;
 
 
@@ -19,6 +20,7 @@ http {
                       '"$http_user_agent" "$http_x_forwarded_for"';
 
     access_log  /var/log/nginx/access.log  main;
+    access_log  /var/log/nginx/access.local.log  main;
 
     sendfile        on;
     #tcp_nopush     on;

+ 25 - 1
server/api/nginx_log.go

@@ -26,11 +26,12 @@ func tailNginxLog(ws *websocket.Conn, controlChan chan controlStruct, errChan ch
 	defer func() {
 		if err := recover(); err != nil {
 			log.Println("tailNginxLog recovery", err)
+			_ = ws.WriteMessage(websocket.TextMessage, err.([]byte))
 			return
 		}
 	}()
 
-	var control controlStruct
+	control := <-controlChan
 
 	for {
 		var seek tail.SeekInfo
@@ -52,10 +53,12 @@ func tailNginxLog(ws *websocket.Conn, controlChan chan controlStruct, errChan ch
 				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]
 
 			switch directive.Directive {
@@ -66,11 +69,27 @@ func tailNginxLog(ws *websocket.Conn, controlChan chan controlStruct, errChan ch
 				return
 			}
 
+			if directive.Params == "" {
+				errChan <- errors.New("directive.Params is empty")
+				return
+			}
+
 			logPath = directive.Params
 
 		case "error":
+			if settings.NginxLogSettings.ErrorLogPath == "" {
+				errChan <- errors.New("settings.NginxLogSettings.ErrorLogPath is empty," +
+					" see https://github.com/0xJacky/nginx-ui/wiki/Nginx-Log-Configuration for more information")
+				return
+			}
 			logPath = settings.NginxLogSettings.ErrorLogPath
+
 		default:
+			if settings.NginxLogSettings.AccessLogPath == "" {
+				errChan <- errors.New("settings.NginxLogSettings.AccessLogPath is empty," +
+					" see https://github.com/0xJacky/nginx-ui/wiki/Nginx-Log-Configuration for more information\"")
+				return
+			}
 			logPath = settings.NginxLogSettings.AccessLogPath
 		}
 
@@ -88,6 +107,10 @@ func tailNginxLog(ws *websocket.Conn, controlChan chan controlStruct, errChan ch
 			select {
 			case line := <-t.Lines:
 				// Print the text of each received line
+				if line == nil {
+					continue
+				}
+
 				err = ws.WriteMessage(websocket.TextMessage, []byte(line.Text))
 
 				if err != nil {
@@ -109,6 +132,7 @@ func handleLogControl(ws *websocket.Conn, controlChan chan controlStruct, errCha
 	defer func() {
 		if err := recover(); err != nil {
 			log.Println("tailNginxLog recovery", err)
+			_ = ws.WriteMessage(websocket.TextMessage, err.([]byte))
 			return
 		}
 	}()

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels