From 0fa98703cd0319d091bf292e83239f406a6156b1 Mon Sep 17 00:00:00 2001 From: Jacky Date: Sun, 25 Feb 2024 20:45:45 +0800 Subject: [PATCH] feat: logrotate cron task for docker users #255 --- api/system/settings.go | 21 +++++-- app/src/language/en/app.po | 55 ++++++++++++---- app/src/language/es/app.po | 55 ++++++++++++---- app/src/language/fr_FR/app.po | 55 ++++++++++++---- app/src/language/messages.pot | 48 ++++++++++---- app/src/language/ru_RU/app.po | 59 ++++++++++++++---- app/src/language/vi_VN/app.po | 55 ++++++++++++---- app/src/language/zh_CN/app.mo | Bin 22580 -> 23553 bytes app/src/language/zh_CN/app.po | 58 +++++++++++++---- app/src/language/zh_TW/app.po | 55 ++++++++++++---- .../views/preference/LogrotateSettings.vue | 41 ++++++++++++ app/src/views/preference/Preference.vue | 17 +++-- app/src/views/preference/typedef.ts | 10 ++- docs/.vitepress/config/en.ts | 3 +- docs/.vitepress/config/zh_CN.ts | 3 +- docs/.vitepress/config/zh_TW.ts | 3 +- docs/guide/config-logrotate.md | 31 +++++++++ docs/guide/config-nginx.md | 2 - docs/zh_CN/guide/config-logrotate.md | 30 +++++++++ docs/zh_TW/guide/config-logrotate.md | 29 +++++++++ internal/cron/cron.go | 52 +++++++++++++++ internal/cron/cron_test.go | 22 +++++++ internal/kernal/boot.go | 11 +++- internal/logrotate/logrotate.go | 45 +++++++++++++ settings/logrotate.go | 13 ++++ settings/settings.go | 9 +-- 26 files changed, 663 insertions(+), 119 deletions(-) create mode 100644 app/src/views/preference/LogrotateSettings.vue create mode 100644 docs/guide/config-logrotate.md create mode 100644 docs/zh_CN/guide/config-logrotate.md create mode 100644 docs/zh_TW/guide/config-logrotate.md create mode 100644 internal/cron/cron.go create mode 100644 internal/cron/cron_test.go create mode 100644 internal/logrotate/logrotate.go create mode 100644 settings/logrotate.go diff --git a/api/system/settings.go b/api/system/settings.go index df315b11..5e18dff9 100644 --- a/api/system/settings.go +++ b/api/system/settings.go @@ -2,6 +2,7 @@ package system import ( "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/cron" "github.com/0xJacky/Nginx-UI/settings" "github.com/gin-gonic/gin" "net/http" @@ -10,26 +11,34 @@ import ( func GetSettings(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ - "server": settings.ServerSettings, - "nginx": settings.NginxSettings, - "openai": settings.OpenAISettings, + "server": settings.ServerSettings, + "nginx": settings.NginxSettings, + "openai": settings.OpenAISettings, + "logrotate": settings.LogrotateSettings, }) } func SaveSettings(c *gin.Context) { var json struct { - Server settings.Server `json:"server"` - Nginx settings.Nginx `json:"nginx"` - Openai settings.OpenAI `json:"openai"` + Server settings.Server `json:"server"` + Nginx settings.Nginx `json:"nginx"` + Openai settings.OpenAI `json:"openai"` + Logrotate settings.Logrotate `json:"logrotate"` } if !api.BindAndValid(c, &json) { return } + if settings.LogrotateSettings.Enabled != json.Logrotate.Enabled || + settings.LogrotateSettings.Interval != json.Logrotate.Interval { + go cron.RestartLogrotate() + } + fillSettings(&settings.ServerSettings, &json.Server) fillSettings(&settings.NginxSettings, &json.Nginx) fillSettings(&settings.OpenAISettings, &json.Openai) + fillSettings(&settings.LogrotateSettings, &json.Logrotate) settings.ReflectFrom() diff --git a/app/src/language/en/app.po b/app/src/language/en/app.po index f0d8c99d..b92ec265 100644 --- a/app/src/language/en/app.po +++ b/app/src/language/en/app.po @@ -155,7 +155,7 @@ msgstr "Base information" #: src/views/config/ConfigEdit.vue:117 #: src/views/domain/components/RightSettings.vue:76 -#: src/views/preference/Preference.vue:96 +#: src/views/preference/Preference.vue:95 #: src/views/stream/components/RightSettings.vue:76 #, fuzzy msgid "Basic" @@ -255,6 +255,11 @@ msgstr "" msgid "Cleared successfully" msgstr "Disabled successfully" +#: src/views/preference/LogrotateSettings.vue:27 +#, fuzzy +msgid "Command" +msgstr "Comments" + #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:107 #: src/views/domain/ngx_conf/LocationEditor.vue:119 #: src/views/domain/ngx_conf/LocationEditor.vue:88 @@ -503,7 +508,7 @@ msgstr "Are you sure you want to remove this directive?" msgid "Do you want to remove this upstream?" msgstr "Are you sure you want to remove this directive?" -#: src/views/certificate/WildcardCertificate.vue:72 +#: src/views/certificate/WildcardCertificate.vue:100 msgid "Domain" msgstr "" @@ -618,6 +623,7 @@ msgstr "Enable TLS" #: src/views/domain/cert/ChangeCert.vue:44 #: src/views/domain/components/RightSettings.vue:78 #: src/views/domain/DomainEdit.vue:179 src/views/domain/DomainList.vue:32 +#: src/views/preference/LogrotateSettings.vue:24 #: src/views/stream/components/RightSettings.vue:78 #: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:32 msgid "Enabled" @@ -838,12 +844,16 @@ msgstr "Enabled successfully" msgid "Intermediate Certification Authorities: %{issuer}" msgstr "Intermediate Certification Authorities: %{issuer}" +#: src/views/preference/LogrotateSettings.vue:30 +msgid "Interval" +msgstr "" + #: src/views/certificate/Certificate.vue:137 #, fuzzy msgid "Issue wildcard certificate" msgstr "Certificate is valid" -#: src/views/certificate/WildcardCertificate.vue:61 +#: src/views/certificate/WildcardCertificate.vue:89 #, fuzzy msgid "Issue Wildcard Certificate" msgstr "Certificate Status" @@ -857,6 +867,7 @@ msgstr "Enabled successfully" msgid "Jwt Secret" msgstr "" +#: src/views/certificate/WildcardCertificate.vue:107 #: src/views/domain/cert/components/AutoCertStepOne.vue:108 msgid "Key Type" msgstr "" @@ -924,6 +935,20 @@ msgstr "Login successful" msgid "Logout successful" msgstr "Logout successful" +#: src/views/preference/Preference.vue:113 +msgid "Logrotate" +msgstr "" + +#: src/views/preference/LogrotateSettings.vue:17 +msgid "" +"Logrotate, by default, is enabled in most mainstream Linux distributions for " +"users who install Nginx UI on the host machine, so you don't need to modify " +"the parameters on this page. For users who install Nginx UI using Docker " +"containers, you can manually enable this option. The crontab task scheduler " +"of Nginx UI will execute the logrotate command at the interval you set in " +"minutes." +msgstr "" + #: src/views/domain/cert/components/AutoCertStepOne.vue:87 #, fuzzy msgid "" @@ -963,6 +988,10 @@ msgstr "Memory" msgid "Memory and Storage" msgstr "Memory and Storage" +#: src/views/preference/LogrotateSettings.vue:34 +msgid "Minutes" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:256 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:336 @@ -1019,13 +1048,13 @@ msgstr "Network Total Send" msgid "New version released" msgstr "" -#: src/views/certificate/WildcardCertificate.vue:87 +#: src/views/certificate/WildcardCertificate.vue:127 #: src/views/domain/cert/components/ObtainCert.vue:204 #: src/views/domain/DomainAdd.vue:145 msgid "Next" msgstr "Next" -#: src/views/preference/Preference.vue:102 +#: src/views/preference/Preference.vue:101 msgid "Nginx" msgstr "" @@ -1148,7 +1177,7 @@ msgstr "" msgid "Online" msgstr "" -#: src/views/preference/Preference.vue:108 +#: src/views/preference/Preference.vue:107 msgid "OpenAI" msgstr "" @@ -1242,7 +1271,7 @@ msgstr "" msgid "Pre-release" msgstr "" -#: src/routes/index.ts:210 src/views/preference/Preference.vue:91 +#: src/routes/index.ts:210 src/views/preference/Preference.vue:90 msgid "Preference" msgstr "" @@ -1334,7 +1363,7 @@ msgid "Renew Certificate Success" msgstr "Certificate is valid" #: src/views/certificate/RenewCert.vue:25 -#: src/views/certificate/WildcardCertificate.vue:50 +#: src/views/certificate/WildcardCertificate.vue:51 #, fuzzy msgid "Renew successfully" msgstr "Enabled successfully" @@ -1368,7 +1397,7 @@ msgstr "" #: src/views/certificate/CertificateEditor.vue:245 #: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:263 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121 -#: src/views/preference/Preference.vue:119 src/views/stream/StreamEdit.vue:253 +#: src/views/preference/Preference.vue:124 src/views/stream/StreamEdit.vue:253 msgid "Save" msgstr "Save" @@ -1383,7 +1412,7 @@ msgstr "Save error %{msg}" #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:42 #: src/views/certificate/CertificateEditor.vue:48 -#: src/views/preference/Preference.vue:61 +#: src/views/preference/Preference.vue:60 #, fuzzy msgid "Save successfully" msgstr "Saved successfully" @@ -1416,7 +1445,7 @@ msgstr "Send" #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:45 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:157 #: src/views/config/ConfigEdit.vue:42 src/views/domain/DomainList.vue:84 -#: src/views/other/Install.vue:72 src/views/preference/Preference.vue:65 +#: src/views/other/Install.vue:72 src/views/preference/Preference.vue:64 #: src/views/stream/StreamList.vue:116 src/views/stream/StreamList.vue:84 #: src/views/system/Upgrade.vue:45 msgid "Server error" @@ -1617,6 +1646,10 @@ msgstr "" msgid "This field should not be empty" msgstr "" +#: src/views/preference/LogrotateSettings.vue:16 +msgid "Tips" +msgstr "" + #: src/views/notification/Notification.vue:21 msgid "Title" msgstr "" diff --git a/app/src/language/es/app.po b/app/src/language/es/app.po index f471e773..c105d045 100644 --- a/app/src/language/es/app.po +++ b/app/src/language/es/app.po @@ -152,7 +152,7 @@ msgstr "Información general" #: src/views/config/ConfigEdit.vue:117 #: src/views/domain/components/RightSettings.vue:76 -#: src/views/preference/Preference.vue:96 +#: src/views/preference/Preference.vue:95 #: src/views/stream/components/RightSettings.vue:76 msgid "Basic" msgstr "Básico" @@ -246,6 +246,11 @@ msgstr "Borrar" msgid "Cleared successfully" msgstr "Limpiado exitoso" +#: src/views/preference/LogrotateSettings.vue:27 +#, fuzzy +msgid "Command" +msgstr "Comentarios" + #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:107 #: src/views/domain/ngx_conf/LocationEditor.vue:119 #: src/views/domain/ngx_conf/LocationEditor.vue:88 @@ -480,7 +485,7 @@ msgstr "¿Quieres eliminar este servidor?" msgid "Do you want to remove this upstream?" msgstr "¿Quieres eliminar esta transmisión?" -#: src/views/certificate/WildcardCertificate.vue:72 +#: src/views/certificate/WildcardCertificate.vue:100 msgid "Domain" msgstr "Dominio" @@ -590,6 +595,7 @@ msgstr "Habilitar TLS" #: src/views/domain/cert/ChangeCert.vue:44 #: src/views/domain/components/RightSettings.vue:78 #: src/views/domain/DomainEdit.vue:179 src/views/domain/DomainList.vue:32 +#: src/views/preference/LogrotateSettings.vue:24 #: src/views/stream/components/RightSettings.vue:78 #: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:32 msgid "Enabled" @@ -802,11 +808,15 @@ msgstr "Instalación exitosa" msgid "Intermediate Certification Authorities: %{issuer}" msgstr "Autoridades de certificación intermedias: %{issuer}" +#: src/views/preference/LogrotateSettings.vue:30 +msgid "Interval" +msgstr "" + #: src/views/certificate/Certificate.vue:137 msgid "Issue wildcard certificate" msgstr "Obtener certificado comodín" -#: src/views/certificate/WildcardCertificate.vue:61 +#: src/views/certificate/WildcardCertificate.vue:89 msgid "Issue Wildcard Certificate" msgstr "Obtener certificado Comodín" @@ -818,6 +828,7 @@ msgstr "Certificado emitido con éxito" msgid "Jwt Secret" msgstr "Secreto Jwt" +#: src/views/certificate/WildcardCertificate.vue:107 #: src/views/domain/cert/components/AutoCertStepOne.vue:108 #, fuzzy msgid "Key Type" @@ -881,6 +892,20 @@ msgstr "Acceso exitoso" msgid "Logout successful" msgstr "Cierre de sesión exitoso" +#: src/views/preference/Preference.vue:113 +msgid "Logrotate" +msgstr "" + +#: src/views/preference/LogrotateSettings.vue:17 +msgid "" +"Logrotate, by default, is enabled in most mainstream Linux distributions for " +"users who install Nginx UI on the host machine, so you don't need to modify " +"the parameters on this page. For users who install Nginx UI using Docker " +"containers, you can manually enable this option. The crontab task scheduler " +"of Nginx UI will execute the logrotate command at the interval you set in " +"minutes." +msgstr "" + #: src/views/domain/cert/components/AutoCertStepOne.vue:87 msgid "" "Make sure you have configured a reverse proxy for .well-known directory to " @@ -917,6 +942,10 @@ msgstr "Memoria" msgid "Memory and Storage" msgstr "Memoria y almacenamiento" +#: src/views/preference/LogrotateSettings.vue:34 +msgid "Minutes" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:256 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:336 @@ -970,13 +999,13 @@ msgstr "Total enviado por la red" msgid "New version released" msgstr "Se liberó una nueva versión" -#: src/views/certificate/WildcardCertificate.vue:87 +#: src/views/certificate/WildcardCertificate.vue:127 #: src/views/domain/cert/components/ObtainCert.vue:204 #: src/views/domain/DomainAdd.vue:145 msgid "Next" msgstr "Siguiente" -#: src/views/preference/Preference.vue:102 +#: src/views/preference/Preference.vue:101 msgid "Nginx" msgstr "Nginx" @@ -1093,7 +1122,7 @@ msgstr "Una vez que se complete la verificación, los registros se eliminarán." msgid "Online" msgstr "En línea" -#: src/views/preference/Preference.vue:108 +#: src/views/preference/Preference.vue:107 msgid "OpenAI" msgstr "OpenAI" @@ -1195,7 +1224,7 @@ msgstr "¡Seleccione al menos un nodo!" msgid "Pre-release" msgstr "Prelanzamiento" -#: src/routes/index.ts:210 src/views/preference/Preference.vue:91 +#: src/routes/index.ts:210 src/views/preference/Preference.vue:90 msgid "Preference" msgstr "Configuración" @@ -1280,7 +1309,7 @@ msgid "Renew Certificate Success" msgstr "Renovado de Certificado exitoso" #: src/views/certificate/RenewCert.vue:25 -#: src/views/certificate/WildcardCertificate.vue:50 +#: src/views/certificate/WildcardCertificate.vue:51 msgid "Renew successfully" msgstr "Renovado con éxito" @@ -1312,7 +1341,7 @@ msgstr "Corriendo" #: src/views/certificate/CertificateEditor.vue:245 #: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:263 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121 -#: src/views/preference/Preference.vue:119 src/views/stream/StreamEdit.vue:253 +#: src/views/preference/Preference.vue:124 src/views/stream/StreamEdit.vue:253 msgid "Save" msgstr "Guardar" @@ -1327,7 +1356,7 @@ msgstr "Error al guardar %{msg}" #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:42 #: src/views/certificate/CertificateEditor.vue:48 -#: src/views/preference/Preference.vue:61 +#: src/views/preference/Preference.vue:60 msgid "Save successfully" msgstr "Guardado con éxito" @@ -1358,7 +1387,7 @@ msgstr "Enviado" #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:45 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:157 #: src/views/config/ConfigEdit.vue:42 src/views/domain/DomainList.vue:84 -#: src/views/other/Install.vue:72 src/views/preference/Preference.vue:65 +#: src/views/other/Install.vue:72 src/views/preference/Preference.vue:64 #: src/views/stream/StreamList.vue:116 src/views/stream/StreamList.vue:84 #: src/views/system/Upgrade.vue:45 msgid "Server error" @@ -1548,6 +1577,10 @@ msgstr "Este campo es obligatorio" msgid "This field should not be empty" msgstr "Este campo no debe estar vacío" +#: src/views/preference/LogrotateSettings.vue:16 +msgid "Tips" +msgstr "" + #: src/views/notification/Notification.vue:21 msgid "Title" msgstr "Título" diff --git a/app/src/language/fr_FR/app.po b/app/src/language/fr_FR/app.po index 0c39dafe..c0231a7a 100644 --- a/app/src/language/fr_FR/app.po +++ b/app/src/language/fr_FR/app.po @@ -155,7 +155,7 @@ msgstr "Information générale" #: src/views/config/ConfigEdit.vue:117 #: src/views/domain/components/RightSettings.vue:76 -#: src/views/preference/Preference.vue:96 +#: src/views/preference/Preference.vue:95 #: src/views/stream/components/RightSettings.vue:76 msgid "Basic" msgstr "Basique" @@ -253,6 +253,11 @@ msgstr "Effacer" msgid "Cleared successfully" msgstr "Désactivé avec succès" +#: src/views/preference/LogrotateSettings.vue:27 +#, fuzzy +msgid "Command" +msgstr "Commentaires" + #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:107 #: src/views/domain/ngx_conf/LocationEditor.vue:119 #: src/views/domain/ngx_conf/LocationEditor.vue:88 @@ -497,7 +502,7 @@ msgstr "Voulez-vous supprimer ce serveur ?" msgid "Do you want to remove this upstream?" msgstr "Voulez-vous supprimer ce serveur ?" -#: src/views/certificate/WildcardCertificate.vue:72 +#: src/views/certificate/WildcardCertificate.vue:100 msgid "Domain" msgstr "" @@ -615,6 +620,7 @@ msgstr "Activer TLS" #: src/views/domain/cert/ChangeCert.vue:44 #: src/views/domain/components/RightSettings.vue:78 #: src/views/domain/DomainEdit.vue:179 src/views/domain/DomainList.vue:32 +#: src/views/preference/LogrotateSettings.vue:24 #: src/views/stream/components/RightSettings.vue:78 #: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:32 msgid "Enabled" @@ -836,12 +842,16 @@ msgstr "Installé avec succès" msgid "Intermediate Certification Authorities: %{issuer}" msgstr "Autorités de certification intermédiaires : %{issuer}" +#: src/views/preference/LogrotateSettings.vue:30 +msgid "Interval" +msgstr "" + #: src/views/certificate/Certificate.vue:137 #, fuzzy msgid "Issue wildcard certificate" msgstr "Obtenir un certificat" -#: src/views/certificate/WildcardCertificate.vue:61 +#: src/views/certificate/WildcardCertificate.vue:89 #, fuzzy msgid "Issue Wildcard Certificate" msgstr "État du certificat" @@ -854,6 +864,7 @@ msgstr "Certificat délivré avec succès" msgid "Jwt Secret" msgstr "Secret Jwt" +#: src/views/certificate/WildcardCertificate.vue:107 #: src/views/domain/cert/components/AutoCertStepOne.vue:108 #, fuzzy msgid "Key Type" @@ -924,6 +935,20 @@ msgstr "Connexion réussie" msgid "Logout successful" msgstr "Déconnexion réussie" +#: src/views/preference/Preference.vue:113 +msgid "Logrotate" +msgstr "" + +#: src/views/preference/LogrotateSettings.vue:17 +msgid "" +"Logrotate, by default, is enabled in most mainstream Linux distributions for " +"users who install Nginx UI on the host machine, so you don't need to modify " +"the parameters on this page. For users who install Nginx UI using Docker " +"containers, you can manually enable this option. The crontab task scheduler " +"of Nginx UI will execute the logrotate command at the interval you set in " +"minutes." +msgstr "" + #: src/views/domain/cert/components/AutoCertStepOne.vue:87 #, fuzzy msgid "" @@ -963,6 +988,10 @@ msgstr "Mémoire" msgid "Memory and Storage" msgstr "Mémoire et stockage" +#: src/views/preference/LogrotateSettings.vue:34 +msgid "Minutes" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:256 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:336 @@ -1017,13 +1046,13 @@ msgstr "Envoi total réseau" msgid "New version released" msgstr "Nouvelle version publiée" -#: src/views/certificate/WildcardCertificate.vue:87 +#: src/views/certificate/WildcardCertificate.vue:127 #: src/views/domain/cert/components/ObtainCert.vue:204 #: src/views/domain/DomainAdd.vue:145 msgid "Next" msgstr "Suivant" -#: src/views/preference/Preference.vue:102 +#: src/views/preference/Preference.vue:101 #, fuzzy msgid "Nginx" msgstr "Journal Nginx" @@ -1144,7 +1173,7 @@ msgstr "" msgid "Online" msgstr "" -#: src/views/preference/Preference.vue:108 +#: src/views/preference/Preference.vue:107 msgid "OpenAI" msgstr "OpenAI" @@ -1244,7 +1273,7 @@ msgstr "" msgid "Pre-release" msgstr "" -#: src/routes/index.ts:210 src/views/preference/Preference.vue:91 +#: src/routes/index.ts:210 src/views/preference/Preference.vue:90 msgid "Preference" msgstr "Préférence" @@ -1337,7 +1366,7 @@ msgid "Renew Certificate Success" msgstr "Changer de certificat" #: src/views/certificate/RenewCert.vue:25 -#: src/views/certificate/WildcardCertificate.vue:50 +#: src/views/certificate/WildcardCertificate.vue:51 #, fuzzy msgid "Renew successfully" msgstr "Activé avec succès" @@ -1370,7 +1399,7 @@ msgstr "En cours d'éxécution" #: src/views/certificate/CertificateEditor.vue:245 #: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:263 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121 -#: src/views/preference/Preference.vue:119 src/views/stream/StreamEdit.vue:253 +#: src/views/preference/Preference.vue:124 src/views/stream/StreamEdit.vue:253 msgid "Save" msgstr "Enregistrer" @@ -1385,7 +1414,7 @@ msgstr "Enregistrer l'erreur %{msg}" #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:42 #: src/views/certificate/CertificateEditor.vue:48 -#: src/views/preference/Preference.vue:61 +#: src/views/preference/Preference.vue:60 msgid "Save successfully" msgstr "Sauvegarde réussie" @@ -1416,7 +1445,7 @@ msgstr "Envoyer" #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:45 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:157 #: src/views/config/ConfigEdit.vue:42 src/views/domain/DomainList.vue:84 -#: src/views/other/Install.vue:72 src/views/preference/Preference.vue:65 +#: src/views/other/Install.vue:72 src/views/preference/Preference.vue:64 #: src/views/stream/StreamList.vue:116 src/views/stream/StreamList.vue:84 #: src/views/system/Upgrade.vue:45 msgid "Server error" @@ -1620,6 +1649,10 @@ msgstr "" msgid "This field should not be empty" msgstr "" +#: src/views/preference/LogrotateSettings.vue:16 +msgid "Tips" +msgstr "" + #: src/views/notification/Notification.vue:21 msgid "Title" msgstr "" diff --git a/app/src/language/messages.pot b/app/src/language/messages.pot index bf1316b9..083c7575 100644 --- a/app/src/language/messages.pot +++ b/app/src/language/messages.pot @@ -149,7 +149,7 @@ msgstr "" #: src/views/config/ConfigEdit.vue:117 #: src/views/domain/components/RightSettings.vue:76 -#: src/views/preference/Preference.vue:96 +#: src/views/preference/Preference.vue:95 #: src/views/stream/components/RightSettings.vue:76 msgid "Basic" msgstr "" @@ -245,6 +245,10 @@ msgstr "" msgid "Cleared successfully" msgstr "" +#: src/views/preference/LogrotateSettings.vue:27 +msgid "Command" +msgstr "" + #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:107 #: src/views/domain/ngx_conf/LocationEditor.vue:119 #: src/views/domain/ngx_conf/LocationEditor.vue:88 @@ -484,7 +488,7 @@ msgstr "" msgid "Do you want to remove this upstream?" msgstr "" -#: src/views/certificate/WildcardCertificate.vue:72 +#: src/views/certificate/WildcardCertificate.vue:100 msgid "Domain" msgstr "" @@ -595,6 +599,7 @@ msgstr "" #: src/views/domain/components/RightSettings.vue:78 #: src/views/domain/DomainEdit.vue:179 #: src/views/domain/DomainList.vue:32 +#: src/views/preference/LogrotateSettings.vue:24 #: src/views/stream/components/RightSettings.vue:78 #: src/views/stream/StreamEdit.vue:170 #: src/views/stream/StreamList.vue:32 @@ -814,11 +819,15 @@ msgstr "" msgid "Intermediate Certification Authorities: %{issuer}" msgstr "" +#: src/views/preference/LogrotateSettings.vue:30 +msgid "Interval" +msgstr "" + #: src/views/certificate/Certificate.vue:137 msgid "Issue wildcard certificate" msgstr "" -#: src/views/certificate/WildcardCertificate.vue:61 +#: src/views/certificate/WildcardCertificate.vue:89 msgid "Issue Wildcard Certificate" msgstr "" @@ -830,6 +839,7 @@ msgstr "" msgid "Jwt Secret" msgstr "" +#: src/views/certificate/WildcardCertificate.vue:107 #: src/views/domain/cert/components/AutoCertStepOne.vue:108 msgid "Key Type" msgstr "" @@ -894,6 +904,14 @@ msgstr "" msgid "Logout successful" msgstr "" +#: src/views/preference/Preference.vue:113 +msgid "Logrotate" +msgstr "" + +#: src/views/preference/LogrotateSettings.vue:17 +msgid "Logrotate, by default, is enabled in most mainstream Linux distributions for users who install Nginx UI on the host machine, so you don't need to modify the parameters on this page. For users who install Nginx UI using Docker containers, you can manually enable this option. The crontab task scheduler of Nginx UI will execute the logrotate command at the interval you set in minutes." +msgstr "" + #: src/views/domain/cert/components/AutoCertStepOne.vue:87 msgid "Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort before obtaining the certificate." msgstr "" @@ -929,6 +947,10 @@ msgstr "" msgid "Memory and Storage" msgstr "" +#: src/views/preference/LogrotateSettings.vue:34 +msgid "Minutes" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:256 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:336 @@ -985,13 +1007,13 @@ msgstr "" msgid "New version released" msgstr "" -#: src/views/certificate/WildcardCertificate.vue:87 +#: src/views/certificate/WildcardCertificate.vue:127 #: src/views/domain/cert/components/ObtainCert.vue:204 #: src/views/domain/DomainAdd.vue:145 msgid "Next" msgstr "" -#: src/views/preference/Preference.vue:102 +#: src/views/preference/Preference.vue:101 msgid "Nginx" msgstr "" @@ -1112,7 +1134,7 @@ msgstr "" msgid "Online" msgstr "" -#: src/views/preference/Preference.vue:108 +#: src/views/preference/Preference.vue:107 msgid "OpenAI" msgstr "" @@ -1203,7 +1225,7 @@ msgid "Pre-release" msgstr "" #: src/routes/index.ts:210 -#: src/views/preference/Preference.vue:91 +#: src/views/preference/Preference.vue:90 msgid "Preference" msgstr "" @@ -1288,7 +1310,7 @@ msgid "Renew Certificate Success" msgstr "" #: src/views/certificate/RenewCert.vue:25 -#: src/views/certificate/WildcardCertificate.vue:50 +#: src/views/certificate/WildcardCertificate.vue:51 msgid "Renew successfully" msgstr "" @@ -1321,7 +1343,7 @@ msgstr "" #: src/views/config/ConfigEdit.vue:98 #: src/views/domain/DomainEdit.vue:263 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121 -#: src/views/preference/Preference.vue:119 +#: src/views/preference/Preference.vue:124 #: src/views/stream/StreamEdit.vue:253 msgid "Save" msgstr "" @@ -1338,7 +1360,7 @@ msgstr "" #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:42 #: src/views/certificate/CertificateEditor.vue:48 -#: src/views/preference/Preference.vue:61 +#: src/views/preference/Preference.vue:60 msgid "Save successfully" msgstr "" @@ -1372,7 +1394,7 @@ msgstr "" #: src/views/config/ConfigEdit.vue:42 #: src/views/domain/DomainList.vue:84 #: src/views/other/Install.vue:72 -#: src/views/preference/Preference.vue:65 +#: src/views/preference/Preference.vue:64 #: src/views/stream/StreamList.vue:116 #: src/views/stream/StreamList.vue:84 #: src/views/system/Upgrade.vue:45 @@ -1557,6 +1579,10 @@ msgstr "" msgid "This field should not be empty" msgstr "" +#: src/views/preference/LogrotateSettings.vue:16 +msgid "Tips" +msgstr "" + #: src/views/notification/Notification.vue:21 msgid "Title" msgstr "" diff --git a/app/src/language/ru_RU/app.po b/app/src/language/ru_RU/app.po index f4945102..670514da 100644 --- a/app/src/language/ru_RU/app.po +++ b/app/src/language/ru_RU/app.po @@ -155,7 +155,7 @@ msgstr "Основная информация" #: src/views/config/ConfigEdit.vue:117 #: src/views/domain/components/RightSettings.vue:76 -#: src/views/preference/Preference.vue:96 +#: src/views/preference/Preference.vue:95 #: src/views/stream/components/RightSettings.vue:76 #, fuzzy msgid "Basic" @@ -255,6 +255,11 @@ msgstr "Очистить" msgid "Cleared successfully" msgstr "Отключено успешно" +#: src/views/preference/LogrotateSettings.vue:27 +#, fuzzy +msgid "Command" +msgstr "Комментарии" + #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:107 #: src/views/domain/ngx_conf/LocationEditor.vue:119 #: src/views/domain/ngx_conf/LocationEditor.vue:88 @@ -503,7 +508,7 @@ msgstr "Вы хотите удалить этот сервер?" msgid "Do you want to remove this upstream?" msgstr "Вы хотите удалить этот сервер?" -#: src/views/certificate/WildcardCertificate.vue:72 +#: src/views/certificate/WildcardCertificate.vue:100 msgid "Domain" msgstr "" @@ -620,6 +625,7 @@ msgstr "Включить TLS" #: src/views/domain/cert/ChangeCert.vue:44 #: src/views/domain/components/RightSettings.vue:78 #: src/views/domain/DomainEdit.vue:179 src/views/domain/DomainList.vue:32 +#: src/views/preference/LogrotateSettings.vue:24 #: src/views/stream/components/RightSettings.vue:78 #: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:32 msgid "Enabled" @@ -841,12 +847,16 @@ msgstr "Установленно" msgid "Intermediate Certification Authorities: %{issuer}" msgstr "Промежуточные центры сертификации: %{issuer}" +#: src/views/preference/LogrotateSettings.vue:30 +msgid "Interval" +msgstr "" + #: src/views/certificate/Certificate.vue:137 #, fuzzy msgid "Issue wildcard certificate" msgstr "Получить сертификат" -#: src/views/certificate/WildcardCertificate.vue:61 +#: src/views/certificate/WildcardCertificate.vue:89 #, fuzzy msgid "Issue Wildcard Certificate" msgstr "Статус сертификата" @@ -860,6 +870,7 @@ msgstr "Сертификат успешно выдан" msgid "Jwt Secret" msgstr "" +#: src/views/certificate/WildcardCertificate.vue:107 #: src/views/domain/cert/components/AutoCertStepOne.vue:108 #, fuzzy msgid "Key Type" @@ -928,6 +939,20 @@ msgstr "Авторизация успешна" msgid "Logout successful" msgstr "Выход выполнен успешно" +#: src/views/preference/Preference.vue:113 +msgid "Logrotate" +msgstr "" + +#: src/views/preference/LogrotateSettings.vue:17 +msgid "" +"Logrotate, by default, is enabled in most mainstream Linux distributions for " +"users who install Nginx UI on the host machine, so you don't need to modify " +"the parameters on this page. For users who install Nginx UI using Docker " +"containers, you can manually enable this option. The crontab task scheduler " +"of Nginx UI will execute the logrotate command at the interval you set in " +"minutes." +msgstr "" + #: src/views/domain/cert/components/AutoCertStepOne.vue:87 #, fuzzy msgid "" @@ -967,6 +992,10 @@ msgstr "Память" msgid "Memory and Storage" msgstr "Память и хранилище" +#: src/views/preference/LogrotateSettings.vue:34 +msgid "Minutes" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:256 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:336 @@ -1023,13 +1052,13 @@ msgstr "Всего отправлено" msgid "New version released" msgstr "Вышла новая версия" -#: src/views/certificate/WildcardCertificate.vue:87 +#: src/views/certificate/WildcardCertificate.vue:127 #: src/views/domain/cert/components/ObtainCert.vue:204 #: src/views/domain/DomainAdd.vue:145 msgid "Next" msgstr "Дальше" -#: src/views/preference/Preference.vue:102 +#: src/views/preference/Preference.vue:101 #, fuzzy msgid "Nginx" msgstr "Журнал" @@ -1153,7 +1182,7 @@ msgstr "" msgid "Online" msgstr "" -#: src/views/preference/Preference.vue:108 +#: src/views/preference/Preference.vue:107 msgid "OpenAI" msgstr "" @@ -1249,7 +1278,7 @@ msgstr "" msgid "Pre-release" msgstr "" -#: src/routes/index.ts:210 src/views/preference/Preference.vue:91 +#: src/routes/index.ts:210 src/views/preference/Preference.vue:90 msgid "Preference" msgstr "Настройки" @@ -1341,7 +1370,7 @@ msgid "Renew Certificate Success" msgstr "Сертификат действителен" #: src/views/certificate/RenewCert.vue:25 -#: src/views/certificate/WildcardCertificate.vue:50 +#: src/views/certificate/WildcardCertificate.vue:51 #, fuzzy msgid "Renew successfully" msgstr "Активировано успешно" @@ -1375,7 +1404,7 @@ msgstr "Выполняется" #: src/views/certificate/CertificateEditor.vue:245 #: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:263 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121 -#: src/views/preference/Preference.vue:119 src/views/stream/StreamEdit.vue:253 +#: src/views/preference/Preference.vue:124 src/views/stream/StreamEdit.vue:253 msgid "Save" msgstr "Сохранить" @@ -1390,7 +1419,7 @@ msgstr "Ошибка сохранения %{msg}" #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:42 #: src/views/certificate/CertificateEditor.vue:48 -#: src/views/preference/Preference.vue:61 +#: src/views/preference/Preference.vue:60 #, fuzzy msgid "Save successfully" msgstr "Успешно сохранено" @@ -1423,7 +1452,7 @@ msgstr "Отправлено" #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:45 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:157 #: src/views/config/ConfigEdit.vue:42 src/views/domain/DomainList.vue:84 -#: src/views/other/Install.vue:72 src/views/preference/Preference.vue:65 +#: src/views/other/Install.vue:72 src/views/preference/Preference.vue:64 #: src/views/stream/StreamList.vue:116 src/views/stream/StreamList.vue:84 #: src/views/system/Upgrade.vue:45 msgid "Server error" @@ -1625,6 +1654,10 @@ msgstr "" msgid "This field should not be empty" msgstr "Это поле обязательно к заполнению" +#: src/views/preference/LogrotateSettings.vue:16 +msgid "Tips" +msgstr "" + #: src/views/notification/Notification.vue:21 msgid "Title" msgstr "Заголовок" @@ -1723,8 +1756,8 @@ msgid "" "We will add one or more TXT records to the DNS records of your domain for " "ownership verification." msgstr "" -"Мы добавим одну или несколько записей TXT в DNS записи вашего домена для" -"подтверждение права собственности" +"Мы добавим одну или несколько записей TXT в DNS записи вашего домена " +"дляподтверждение права собственности" #: src/views/domain/cert/components/ObtainCert.vue:135 msgid "" diff --git a/app/src/language/vi_VN/app.po b/app/src/language/vi_VN/app.po index c8ecc28e..22e9f3c2 100644 --- a/app/src/language/vi_VN/app.po +++ b/app/src/language/vi_VN/app.po @@ -155,7 +155,7 @@ msgstr "Thông tin" #: src/views/config/ConfigEdit.vue:117 #: src/views/domain/components/RightSettings.vue:76 -#: src/views/preference/Preference.vue:96 +#: src/views/preference/Preference.vue:95 #: src/views/stream/components/RightSettings.vue:76 #, fuzzy msgid "Basic" @@ -255,6 +255,11 @@ msgstr "Xoá" msgid "Cleared successfully" msgstr "Đã xóa thành công" +#: src/views/preference/LogrotateSettings.vue:27 +#, fuzzy +msgid "Command" +msgstr "Bình luận" + #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:107 #: src/views/domain/ngx_conf/LocationEditor.vue:119 #: src/views/domain/ngx_conf/LocationEditor.vue:88 @@ -504,7 +509,7 @@ msgstr "Bạn muốn xóa máy chủ này ?" msgid "Do you want to remove this upstream?" msgstr "Bạn muốn xóa máy chủ này ?" -#: src/views/certificate/WildcardCertificate.vue:72 +#: src/views/certificate/WildcardCertificate.vue:100 msgid "Domain" msgstr "" @@ -621,6 +626,7 @@ msgstr "Bật TLS" #: src/views/domain/cert/ChangeCert.vue:44 #: src/views/domain/components/RightSettings.vue:78 #: src/views/domain/DomainEdit.vue:179 src/views/domain/DomainList.vue:32 +#: src/views/preference/LogrotateSettings.vue:24 #: src/views/stream/components/RightSettings.vue:78 #: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:32 msgid "Enabled" @@ -843,12 +849,16 @@ msgstr "Cài đặt thành công" msgid "Intermediate Certification Authorities: %{issuer}" msgstr "Cơ quan cấp chứng chỉ: %{issuer}" +#: src/views/preference/LogrotateSettings.vue:30 +msgid "Interval" +msgstr "" + #: src/views/certificate/Certificate.vue:137 #, fuzzy msgid "Issue wildcard certificate" msgstr "Gia hạn SSL" -#: src/views/certificate/WildcardCertificate.vue:61 +#: src/views/certificate/WildcardCertificate.vue:89 #, fuzzy msgid "Issue Wildcard Certificate" msgstr "Thêm chứng chỉ SSL" @@ -862,6 +872,7 @@ msgstr "Cấp chứng chỉ thành công" msgid "Jwt Secret" msgstr "" +#: src/views/certificate/WildcardCertificate.vue:107 #: src/views/domain/cert/components/AutoCertStepOne.vue:108 #, fuzzy msgid "Key Type" @@ -930,6 +941,20 @@ msgstr "Đăng nhập thành công" msgid "Logout successful" msgstr "Đã đăng xuất" +#: src/views/preference/Preference.vue:113 +msgid "Logrotate" +msgstr "" + +#: src/views/preference/LogrotateSettings.vue:17 +msgid "" +"Logrotate, by default, is enabled in most mainstream Linux distributions for " +"users who install Nginx UI on the host machine, so you don't need to modify " +"the parameters on this page. For users who install Nginx UI using Docker " +"containers, you can manually enable this option. The crontab task scheduler " +"of Nginx UI will execute the logrotate command at the interval you set in " +"minutes." +msgstr "" + #: src/views/domain/cert/components/AutoCertStepOne.vue:87 #, fuzzy msgid "" @@ -968,6 +993,10 @@ msgstr "Memory" msgid "Memory and Storage" msgstr "Memory và Storage" +#: src/views/preference/LogrotateSettings.vue:34 +msgid "Minutes" +msgstr "" + #: src/components/ChatGPT/ChatGPT.vue:256 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:336 @@ -1024,13 +1053,13 @@ msgstr "Tổng lưu lượng mạng đã gửi" msgid "New version released" msgstr "Đã có phiên bản mới" -#: src/views/certificate/WildcardCertificate.vue:87 +#: src/views/certificate/WildcardCertificate.vue:127 #: src/views/domain/cert/components/ObtainCert.vue:204 #: src/views/domain/DomainAdd.vue:145 msgid "Next" msgstr "Tiếp theo" -#: src/views/preference/Preference.vue:102 +#: src/views/preference/Preference.vue:101 msgid "Nginx" msgstr "" @@ -1153,7 +1182,7 @@ msgstr "Sau khi quá trình xác minh hoàn tất, bản ghi sẽ bị xóa." msgid "Online" msgstr "Trực tuyến" -#: src/views/preference/Preference.vue:108 +#: src/views/preference/Preference.vue:107 msgid "OpenAI" msgstr "" @@ -1251,7 +1280,7 @@ msgstr "" msgid "Pre-release" msgstr "" -#: src/routes/index.ts:210 src/views/preference/Preference.vue:91 +#: src/routes/index.ts:210 src/views/preference/Preference.vue:90 msgid "Preference" msgstr "Cài đặt" @@ -1343,7 +1372,7 @@ msgid "Renew Certificate Success" msgstr "Gia hạn chứng chỉ SSL thành công" #: src/views/certificate/RenewCert.vue:25 -#: src/views/certificate/WildcardCertificate.vue:50 +#: src/views/certificate/WildcardCertificate.vue:51 #, fuzzy msgid "Renew successfully" msgstr "Gia hạn chứng chỉ SSL" @@ -1377,7 +1406,7 @@ msgstr "Running" #: src/views/certificate/CertificateEditor.vue:245 #: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:263 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121 -#: src/views/preference/Preference.vue:119 src/views/stream/StreamEdit.vue:253 +#: src/views/preference/Preference.vue:124 src/views/stream/StreamEdit.vue:253 msgid "Save" msgstr "Lưu" @@ -1392,7 +1421,7 @@ msgstr "Đã xảy ra lỗi khi lưu %{msg}" #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:42 #: src/views/certificate/CertificateEditor.vue:48 -#: src/views/preference/Preference.vue:61 +#: src/views/preference/Preference.vue:60 #, fuzzy msgid "Save successfully" msgstr "Lưu thành công" @@ -1425,7 +1454,7 @@ msgstr "Gửi" #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:45 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:157 #: src/views/config/ConfigEdit.vue:42 src/views/domain/DomainList.vue:84 -#: src/views/other/Install.vue:72 src/views/preference/Preference.vue:65 +#: src/views/other/Install.vue:72 src/views/preference/Preference.vue:64 #: src/views/stream/StreamList.vue:116 src/views/stream/StreamList.vue:84 #: src/views/system/Upgrade.vue:45 msgid "Server error" @@ -1619,6 +1648,10 @@ msgstr "" msgid "This field should not be empty" msgstr "Trường này không được để trống" +#: src/views/preference/LogrotateSettings.vue:16 +msgid "Tips" +msgstr "" + #: src/views/notification/Notification.vue:21 msgid "Title" msgstr "Tiêu đề" diff --git a/app/src/language/zh_CN/app.mo b/app/src/language/zh_CN/app.mo index acd663231d6bb70d55fa2bbd56523efd4c4e6c09..414fee79c54b201507fdf55519f9e0e245ec0114 100644 GIT binary patch delta 8759 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 a{5aa{k=Ja{=5moMRu*l`J31o0^#1`@mB=Fi delta 7790 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 G5cpqbL +import { useGettext } from 'vue3-gettext' +import { inject } from 'vue' +import type { Settings } from '@/views/preference/typedef' + +const { $gettext } = useGettext() + +const data: Settings = inject('data')! + + + + + diff --git a/app/src/views/preference/Preference.vue b/app/src/views/preference/Preference.vue index 8e68fa75..5dbbc479 100644 --- a/app/src/views/preference/Preference.vue +++ b/app/src/views/preference/Preference.vue @@ -8,6 +8,7 @@ import BasicSettings from '@/views/preference/BasicSettings.vue' import OpenAISettings from '@/views/preference/OpenAISettings.vue' import NginxSettings from '@/views/preference/NginxSettings.vue' import type { Settings } from '@/views/preference/typedef' +import LogrotateSettings from '@/views/preference/LogrotateSettings.vue' const { $gettext } = useGettext() @@ -38,12 +39,10 @@ const data = ref({ proxy: '', token: '', }, - git: { - url: '', - auth_method: '', - username: '', - password: '', - private_key_file_path: '', + logrotate: { + enabled: false, + cmd: '', + interval: 1440, }, }) @@ -109,6 +108,12 @@ onMounted(() => { > + + + diff --git a/app/src/views/preference/typedef.ts b/app/src/views/preference/typedef.ts index ecf32064..29216187 100644 --- a/app/src/views/preference/typedef.ts +++ b/app/src/views/preference/typedef.ts @@ -25,11 +25,9 @@ export interface Settings { proxy: string token: string } - git: { - url: string - auth_method: string - username: string - password: string - private_key_file_path: string + logrotate: { + enabled: boolean + cmd: string + interval: number } } diff --git a/docs/.vitepress/config/en.ts b/docs/.vitepress/config/en.ts index 7c44de77..7a4a138f 100644 --- a/docs/.vitepress/config/en.ts +++ b/docs/.vitepress/config/en.ts @@ -37,7 +37,8 @@ export const enConfig: LocaleSpecificConfig = { {text: 'Server', link: '/guide/config-server'}, {text: 'Nginx', link: '/guide/config-nginx'}, {text: 'Open AI', link: '/guide/config-openai'}, - {text: 'Casdoor', link: '/guide/config-casdoor'} + {text: 'Casdoor', link: '/guide/config-casdoor'}, + {text: 'Logrotate', link: '/guide/config-logrotate'} ] }, { diff --git a/docs/.vitepress/config/zh_CN.ts b/docs/.vitepress/config/zh_CN.ts index 5a4d7307..1f26269d 100644 --- a/docs/.vitepress/config/zh_CN.ts +++ b/docs/.vitepress/config/zh_CN.ts @@ -42,7 +42,8 @@ export const zhCNConfig: LocaleSpecificConfig = { {text: '服务端', link: '/zh_CN/guide/config-server'}, {text: 'Nginx', link: '/zh_CN/guide/config-nginx'}, {text: 'Open AI', link: '/zh_CN/guide/config-openai'}, - {text: 'Casdoor', link: '/zh_CN/guide/config-casdoor'} + {text: 'Casdoor', link: '/zh_CN/guide/config-casdoor'}, + {text: 'Logrotate', link: '/zh_CN/guide/config-logrotate'} ] }, { diff --git a/docs/.vitepress/config/zh_TW.ts b/docs/.vitepress/config/zh_TW.ts index df438fba..9aed7a90 100644 --- a/docs/.vitepress/config/zh_TW.ts +++ b/docs/.vitepress/config/zh_TW.ts @@ -41,7 +41,8 @@ export const zhTWConfig: LocaleSpecificConfig = { {text: '服務端', link: '/zh_TW/guide/config-server'}, {text: 'Nginx', link: '/zh_TW/guide/config-nginx'}, {text: 'Open AI', link: '/zh_TW/guide/config-openai'}, - {text: 'Casdoor', link: '/zh_TW/guide/config-casdoor'} + {text: 'Casdoor', link: '/zh_TW/guide/config-casdoor'}, + {text: 'Logrotate', link: '/zh_CN/guide/config-logrotate'} ] }, { diff --git a/docs/guide/config-logrotate.md b/docs/guide/config-logrotate.md new file mode 100644 index 00000000..77b04a74 --- /dev/null +++ b/docs/guide/config-logrotate.md @@ -0,0 +1,31 @@ +# Logrotate + +In this section, we will introduce configuration options in Nginx UI about logrotate. + +**logrotate** is designed to ease administration of systems that generate large numbers of log files. +It allows automatic rotation, compression, removal, and mailing of log files. +Each log file may be handled daily, weekly, monthly, or when it grows too large. + +By default, logrotate is enabled in most mainstream Linux distributions for users who install Nginx UI on the host machine, +so you don't need to modify anything. + +For users who install Nginx UI using Docker containers, you can manually enable this option. +The crontab task scheduler of Nginx UI will execute the logrotate command at the interval you set in minutes. + +## Enabled +- Type: `bool` +- Default: `false` + +This option is used to enable logrotate crontab task in Nginx UI. + +## CMD +- Type: `string` +- Default: `logrotate /etc/logrotate.d/nginx` + +This option is used to set the logrotate command in Nginx UI. + +## Interval +- Type: `int` +- Default: `1440` + +This option is used to set the interval in minutes of logrotate crontab task in Nginx UI. diff --git a/docs/guide/config-nginx.md b/docs/guide/config-nginx.md index be97bbab..97995535 100644 --- a/docs/guide/config-nginx.md +++ b/docs/guide/config-nginx.md @@ -63,8 +63,6 @@ In Nginx UI v2, we parse the output of the `nginx -V` command to get the default If you need to set a different path, you can use this option. ::: - - ## Service Monitoring and Control In this section, we will introduce configuration options in Nginx UI for monitoring and controlling Nginx services. diff --git a/docs/zh_CN/guide/config-logrotate.md b/docs/zh_CN/guide/config-logrotate.md new file mode 100644 index 00000000..78085a75 --- /dev/null +++ b/docs/zh_CN/guide/config-logrotate.md @@ -0,0 +1,30 @@ +# Logrotate + +在这个部分,我们将介绍 Nginx UI 中关于 logrotate 的配置选项。 + +**logrotate** 旨在简化生成大量日志文件的系统的管理。 +它可以按天、周、月或者文件大小来轮转日志文件,还可以压缩、删除旧的日志文件,以及发送日志文件到指定的邮箱。 + +默认情况下,对于在主机上安装 Nginx UI 的用户,大多数主流的 Linux 发行版都已集成 logrotate, +所以你不需要修改任何东西。 + +对于使用 Docker 容器安装 Nginx UI 的用户,你可以手动启用这个选项。 +Nginx UI 的 crontab 任务调度器将会按照你设定的分钟间隔执行 logrotate 命令。 + +## Enabled +- 类型:`bool` +- 默认值:`false` + +这个选项用于在 Nginx UI 中启用 logrotate crontab 任务。 + +## CMD +- 类型:`string` +- 默认值:`logrotate /etc/logrotate.d/nginx` + +这个选项用于在 Nginx UI 中设置 logrotate 命令。 + +## Interval +- 类型:`int` +- 默认值:`1440` + +这个选项用于在 Nginx UI 中设置 logrotate crontab 任务的分钟间隔。 diff --git a/docs/zh_TW/guide/config-logrotate.md b/docs/zh_TW/guide/config-logrotate.md new file mode 100644 index 00000000..24310fa8 --- /dev/null +++ b/docs/zh_TW/guide/config-logrotate.md @@ -0,0 +1,29 @@ +# Logrotate + +在這個部分,我們將介紹 Nginx UI 中關於 logrotate 的配置選項。 + +**logrotate** 旨在簡化生成大量日誌文件的系統的管理。 +它可以按天、周、月或者文件大小來輪轉日誌文件,還可以壓縮、刪除舊的日誌文件,以及發送日誌文件到指定的郵箱。 +默認情況下,對於在主機上安裝 Nginx UI 的用戶,大多數主流的 Linux 發行版都已集成 logrotate, +所以你不需要修改任何東西。 + +對於使用 Docker 容器安裝 Nginx UI 的用戶,你可以手動啟用這個選項。 +Nginx UI 的 crontab 任務調度器將會按照你設定的分鐘間隔執行 logrotate 命令。 + +## Enabled +- 類型:`bool` +- 默認值:`false` + +這個選項用於在 Nginx UI 中啟用 logrotate crontab 任務。 + +## CMD +- 類型:`string` +- 默認值:`logrotate /etc/logrotate.d/nginx` + +這個選項用於在 Nginx UI 中設置 logrotate 命令。 + +## Interval +- 類型:`int` +- 默認值:`1440` + +這個選項用於在 Nginx UI 中設置 logrotate crontab 任務的分鐘間隔。 diff --git a/internal/cron/cron.go b/internal/cron/cron.go new file mode 100644 index 00000000..450c7c58 --- /dev/null +++ b/internal/cron/cron.go @@ -0,0 +1,52 @@ +package cron + +import ( + "github.com/0xJacky/Nginx-UI/internal/cert" + "github.com/0xJacky/Nginx-UI/internal/logger" + "github.com/0xJacky/Nginx-UI/internal/logrotate" + "github.com/0xJacky/Nginx-UI/settings" + "github.com/go-co-op/gocron" + "time" +) + +var s *gocron.Scheduler + +func init() { + s = gocron.NewScheduler(time.UTC) +} + +var logrotateJob *gocron.Job + +func InitCronJobs() { + job, err := s.Every(30).Minute().SingletonMode().Do(cert.AutoObtain) + + if err != nil { + logger.Fatalf("AutoCert Job: %v, Err: %v\n", job, err) + } + + startLogrotate() + + s.StartAsync() +} + +func RestartLogrotate() { + logger.Debug("Restart Logrotate") + if logrotateJob != nil { + s.RemoveByReference(logrotateJob) + } + + startLogrotate() +} + +func startLogrotate() { + if !settings.LogrotateSettings.Enabled { + return + } + var err error + + logrotateJob, err = s.Every(settings.LogrotateSettings.Interval).Minute().SingletonMode().Do(logrotate.Exec) + + if err != nil { + logger.Fatalf("LogRotate Job: %v, Err: %v\n", logrotateJob, err) + } +} diff --git a/internal/cron/cron_test.go b/internal/cron/cron_test.go new file mode 100644 index 00000000..8b19de90 --- /dev/null +++ b/internal/cron/cron_test.go @@ -0,0 +1,22 @@ +package cron + +import ( + "github.com/0xJacky/Nginx-UI/internal/kernal" + "github.com/0xJacky/Nginx-UI/settings" + "testing" + "time" +) + +func TestRestartLogrotate(t *testing.T) { + settings.Init("../../app.ini") + + kernal.InitDatabase() + + InitCronJobs() + + time.Sleep(5 * time.Second) + + RestartLogrotate() + + time.Sleep(2 * time.Second) +} diff --git a/internal/kernal/boot.go b/internal/kernal/boot.go index ae41e5f2..3d559b50 100644 --- a/internal/kernal/boot.go +++ b/internal/kernal/boot.go @@ -4,6 +4,7 @@ import ( "github.com/0xJacky/Nginx-UI/internal/analytic" "github.com/0xJacky/Nginx-UI/internal/cert" "github.com/0xJacky/Nginx-UI/internal/logger" + "github.com/0xJacky/Nginx-UI/internal/logrotate" "github.com/0xJacky/Nginx-UI/internal/validation" "github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/query" @@ -40,7 +41,7 @@ func Boot() { func InitAfterDatabase() { syncs := []func(){ - InitAutoObtainCert, + InitCronJobs, analytic.RetrieveNodesStatus, } @@ -86,7 +87,7 @@ func InitJsExtensionType() { _ = mime.AddExtensionType(".js", "text/javascript; charset=utf-8") } -func InitAutoObtainCert() { +func InitCronJobs() { s := gocron.NewScheduler(time.UTC) job, err := s.Every(30).Minute().SingletonMode().Do(cert.AutoObtain) @@ -94,5 +95,11 @@ func InitAutoObtainCert() { logger.Fatalf("AutoCert Job: %v, Err: %v\n", job, err) } + job, err = s.Every(settings.LogrotateSettings.Interval).Minute().SingletonMode().Do(logrotate.Exec) + + if err != nil { + logger.Fatalf("LogRotate Job: %v, Err: %v\n", job, err) + } + s.StartAsync() } diff --git a/internal/logrotate/logrotate.go b/internal/logrotate/logrotate.go new file mode 100644 index 00000000..3036ea8f --- /dev/null +++ b/internal/logrotate/logrotate.go @@ -0,0 +1,45 @@ +package logrotate + +import ( + "github.com/0xJacky/Nginx-UI/internal/logger" + "github.com/0xJacky/Nginx-UI/settings" + "os/exec" + "strings" +) + +func Exec() { + if !settings.LogrotateSettings.Enabled { + return + } + + logger.Info("logrotate start") + defer logger.Info("logrotate end") + cmd := strings.Split(settings.LogrotateSettings.CMD, " ") + + if len(cmd) == 0 { + return + } + + var ( + name string + args = make([]string, 0) + ) + + if len(cmd) > 0 { + name = cmd[0] + } + + if len(cmd) > 1 { + args = cmd[1:] + } + + out, err := exec.Command(name, args...).CombinedOutput() + if err != nil { + logger.Error(err, string(out)) + return + } + + if len(out) > 0 { + logger.Debug(string(out)) + } +} diff --git a/settings/logrotate.go b/settings/logrotate.go new file mode 100644 index 00000000..7cc2c962 --- /dev/null +++ b/settings/logrotate.go @@ -0,0 +1,13 @@ +package settings + +type Logrotate struct { + Enabled bool `json:"enabled"` + CMD string `json:"cmd" protect:"true"` + Interval int `json:"interval"` +} + +var LogrotateSettings = Logrotate{ + Enabled: false, + CMD: "logrotate /etc/logrotate.d/nginx", + Interval: 1440, // 24 hours +} diff --git a/settings/settings.go b/settings/settings.go index c133b053..14bcf358 100644 --- a/settings/settings.go +++ b/settings/settings.go @@ -18,10 +18,11 @@ var ( var ConfPath string var sections = map[string]interface{}{ - "server": &ServerSettings, - "nginx": &NginxSettings, - "openai": &OpenAISettings, - "casdoor": &CasdoorSettings, + "server": &ServerSettings, + "nginx": &NginxSettings, + "openai": &OpenAISettings, + "casdoor": &CasdoorSettings, + "logrotate": &LogrotateSettings, } func init() {