Procházet zdrojové kódy

feat(nginx_log): add basic log_list fallback when AdvancedIndexing is disabled

- Introduce in-memory fallback cache and simple rotation grouping
- Route AddLogPath/RemoveLogPathsFromConfig/Get* to fallback when LogFileManager is unavailable
- Preserve existing behavior when AdvancedIndexingEnabled is true
0xJacky před 4 měsíci
rodič
revize
9124b33cf3

+ 86 - 13
app/auto-imports.d.ts

@@ -103,18 +103,91 @@ declare global {
 }
 
 // for vue template auto import
-type UnwrapRefs<T> = {
-  [K in keyof T]: import('vue').UnwrapRef<T[K]>
-}
-namespace _ComponentCustomProperties {
-  const { $gettext, $ngettext, $npgettext, $pgettext }: typeof import('@/gettext')
-  const { App }: typeof import('ant-design-vue')
-  const { EffectScope, computed, createApp, customRef, defineAsyncComponent, defineComponent, effectScope, getCurrentInstance, getCurrentScope, getCurrentWatcher, h, inject, isProxy, isReactive, isReadonly, isRef, isShallow, markRaw, nextTick, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, onWatcherCleanup, provide, reactive, readonly, ref, resolveComponent, shallowReactive, shallowReadonly, shallowRef, toRaw, toRef, toRefs, toValue, triggerRef, unref, useAttrs, useCssModule, useCssVars, useId, useModel, useSlots, useTemplateRef, watch, watchEffect, watchPostEffect, watchSyncEffect }: typeof import('vue')
-  const { T }: typeof import('@/language')
-  const { acceptHMRUpdate, createPinia, defineStore, getActivePinia, mapActions, mapGetters, mapState, mapStores, mapWritableState, setActivePinia, setMapStoreSuffix, storeToRefs }: typeof import('pinia')
-  const { onBeforeRouteLeave, onBeforeRouteUpdate, useLink, useRoute, useRouter }: typeof import('vue-router')
-  const { useGlobalApp }: typeof import('@/composables/useGlobalApp')
-}
+import { UnwrapRef } from 'vue'
 declare module 'vue' {
-  interface ComponentCustomProperties extends UnwrapRefs<typeof _ComponentCustomProperties> {}
+  interface GlobalComponents {}
+  interface ComponentCustomProperties {
+    readonly $gettext: UnwrapRef<typeof import('@/gettext')['$gettext']>
+    readonly $ngettext: UnwrapRef<typeof import('@/gettext')['$ngettext']>
+    readonly $npgettext: UnwrapRef<typeof import('@/gettext')['$npgettext']>
+    readonly $pgettext: UnwrapRef<typeof import('@/gettext')['$pgettext']>
+    readonly App: UnwrapRef<typeof import('ant-design-vue')['App']>
+    readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
+    readonly T: UnwrapRef<typeof import('@/language')['T']>
+    readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
+    readonly computed: UnwrapRef<typeof import('vue')['computed']>
+    readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
+    readonly createPinia: UnwrapRef<typeof import('pinia')['createPinia']>
+    readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
+    readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
+    readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
+    readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']>
+    readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
+    readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
+    readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
+    readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
+    readonly getCurrentWatcher: UnwrapRef<typeof import('vue')['getCurrentWatcher']>
+    readonly h: UnwrapRef<typeof import('vue')['h']>
+    readonly inject: UnwrapRef<typeof import('vue')['inject']>
+    readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
+    readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
+    readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
+    readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
+    readonly isShallow: UnwrapRef<typeof import('vue')['isShallow']>
+    readonly mapActions: UnwrapRef<typeof import('pinia')['mapActions']>
+    readonly mapGetters: UnwrapRef<typeof import('pinia')['mapGetters']>
+    readonly mapState: UnwrapRef<typeof import('pinia')['mapState']>
+    readonly mapStores: UnwrapRef<typeof import('pinia')['mapStores']>
+    readonly mapWritableState: UnwrapRef<typeof import('pinia')['mapWritableState']>
+    readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
+    readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
+    readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
+    readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
+    readonly onBeforeRouteLeave: UnwrapRef<typeof import('vue-router')['onBeforeRouteLeave']>
+    readonly onBeforeRouteUpdate: UnwrapRef<typeof import('vue-router')['onBeforeRouteUpdate']>
+    readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
+    readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
+    readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
+    readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
+    readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
+    readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
+    readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
+    readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
+    readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
+    readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
+    readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
+    readonly onWatcherCleanup: UnwrapRef<typeof import('vue')['onWatcherCleanup']>
+    readonly provide: UnwrapRef<typeof import('vue')['provide']>
+    readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
+    readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
+    readonly ref: UnwrapRef<typeof import('vue')['ref']>
+    readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
+    readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']>
+    readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
+    readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
+    readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
+    readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
+    readonly storeToRefs: UnwrapRef<typeof import('pinia')['storeToRefs']>
+    readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
+    readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
+    readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
+    readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
+    readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
+    readonly unref: UnwrapRef<typeof import('vue')['unref']>
+    readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
+    readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
+    readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
+    readonly useGlobalApp: UnwrapRef<typeof import('@/composables/useGlobalApp')['useGlobalApp']>
+    readonly useId: UnwrapRef<typeof import('vue')['useId']>
+    readonly useLink: UnwrapRef<typeof import('vue-router')['useLink']>
+    readonly useModel: UnwrapRef<typeof import('vue')['useModel']>
+    readonly useRoute: UnwrapRef<typeof import('vue-router')['useRoute']>
+    readonly useRouter: UnwrapRef<typeof import('vue-router')['useRouter']>
+    readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
+    readonly useTemplateRef: UnwrapRef<typeof import('vue')['useTemplateRef']>
+    readonly watch: UnwrapRef<typeof import('vue')['watch']>
+    readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
+    readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
+    readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
+  }
 }

+ 5 - 0
app/components.d.ts

@@ -20,6 +20,9 @@ declare module 'vue' {
     ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
     ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
     ACol: typeof import('ant-design-vue/es')['Col']
+    ACollapse: typeof import('ant-design-vue/es')['Collapse']
+    ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel']
+    AComment: typeof import('ant-design-vue/es')['Comment']
     AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
     ADivider: typeof import('ant-design-vue/es')['Divider']
     ADrawer: typeof import('ant-design-vue/es')['Drawer']
@@ -40,6 +43,7 @@ declare module 'vue' {
     AListItem: typeof import('ant-design-vue/es')['ListItem']
     AListItemMeta: typeof import('ant-design-vue/es')['ListItemMeta']
     AMenu: typeof import('ant-design-vue/es')['Menu']
+    AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider']
     AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
     AModal: typeof import('ant-design-vue/es')['Modal']
     APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
@@ -60,6 +64,7 @@ declare module 'vue' {
     ATabPane: typeof import('ant-design-vue/es')['TabPane']
     ATabs: typeof import('ant-design-vue/es')['Tabs']
     ATag: typeof import('ant-design-vue/es')['Tag']
+    ATextarea: typeof import('ant-design-vue/es')['Textarea']
     ATooltip: typeof import('ant-design-vue/es')['Tooltip']
     ATypographyText: typeof import('ant-design-vue/es')['TypographyText']
     ATypographyTitle: typeof import('ant-design-vue/es')['TypographyTitle']

+ 9 - 9
app/src/language/ar/app.po

@@ -483,7 +483,7 @@ msgstr "فشل النسخ الاحتياطي التلقائي"
 msgid "Auto Backup Storage Failed"
 msgstr "فشل تخزين النسخ الاحتياطي التلقائي"
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr "التحديث التلقائي"
 
@@ -535,7 +535,7 @@ msgstr "متوسط/زيارة الصفحة"
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1519,7 +1519,7 @@ msgstr "يوميًا في الساعة %{time}"
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr "لوحة المعلومات"
 
@@ -2741,11 +2741,11 @@ msgstr "تم تحميل الملف بنجاح"
 msgid "Filename is empty"
 msgstr "اسم الملف فارغ"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr "تصفيه"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr "تصفية محتوى السجل"
 
@@ -4065,7 +4065,7 @@ msgstr "إن Nginx لا يعمل في حاوية أخرى"
 msgid "Nginx is running"
 msgstr "إن Nginx يعمل"
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr "سجل Nginx"
 
@@ -4963,7 +4963,7 @@ msgstr "في قائمة انتظار الفهرسة..."
 msgid "Quick Select"
 msgstr "اختيار سريع"
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr "خام"
 
@@ -6078,7 +6078,7 @@ msgstr "دليل Streams-available غير موجود"
 msgid "Streams-enabled directory not exist"
 msgstr "دليل Streams-enabled غير موجود"
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr "منظم"
 
@@ -7175,7 +7175,7 @@ msgstr "كتابة الشهادة إلى القرص"
 msgid "Yes"
 msgstr "نعم"
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 9 - 9
app/src/language/de_DE/app.po

@@ -495,7 +495,7 @@ msgstr "Automatische Sicherung fehlgeschlagen"
 msgid "Auto Backup Storage Failed"
 msgstr "Automatische Sicherungsspeicherung fehlgeschlagen"
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr "Automatische Aktualisierung"
 
@@ -547,7 +547,7 @@ msgstr "Durchschn./PV"
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1552,7 +1552,7 @@ msgstr "Täglich um %{time}"
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr "Übersicht"
 
@@ -2788,11 +2788,11 @@ msgstr "Datei erfolgreich hochgeladen"
 msgid "Filename is empty"
 msgstr "Der Dateiname ist leer"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr "Filter"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr "Loginhalt filtern"
 
@@ -4125,7 +4125,7 @@ msgstr "Nginx läuft nicht in einem anderen Container"
 msgid "Nginx is running"
 msgstr "Nginx läuft"
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr "Nginx-Log"
 
@@ -5049,7 +5049,7 @@ msgstr "Zur Indizierung in der Warteschlange..."
 msgid "Quick Select"
 msgstr "Schnellauswahl"
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr "Roh"
 
@@ -6185,7 +6185,7 @@ msgstr "Streams-available-Verzeichnis existiert nicht"
 msgid "Streams-enabled directory not exist"
 msgstr "Streams-enabled-Verzeichnis existiert nicht"
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr "Strukturiert"
 
@@ -7322,7 +7322,7 @@ msgstr "Schreibe Zertifikat auf die Festplatte"
 msgid "Yes"
 msgstr "Ja"
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 9 - 9
app/src/language/en/app.po

@@ -461,7 +461,7 @@ msgstr ""
 msgid "Auto Backup Storage Failed"
 msgstr ""
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr ""
 
@@ -513,7 +513,7 @@ msgstr ""
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1450,7 +1450,7 @@ msgstr ""
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr ""
 
@@ -2661,11 +2661,11 @@ msgstr ""
 msgid "Filename is empty"
 msgstr ""
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr ""
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr ""
 
@@ -3954,7 +3954,7 @@ msgstr ""
 msgid "Nginx is running"
 msgstr ""
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr ""
 
@@ -4832,7 +4832,7 @@ msgstr ""
 msgid "Quick Select"
 msgstr ""
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr ""
 
@@ -5929,7 +5929,7 @@ msgstr ""
 msgid "Streams-enabled directory not exist"
 msgstr ""
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr ""
 
@@ -6960,7 +6960,7 @@ msgstr ""
 msgid "Yes"
 msgstr ""
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 9 - 9
app/src/language/es/app.po

@@ -501,7 +501,7 @@ msgstr "Copia de seguridad automática fallida"
 msgid "Auto Backup Storage Failed"
 msgstr "Fallo en el almacenamiento de copia de seguridad automática"
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr "Actualización automática"
 
@@ -553,7 +553,7 @@ msgstr "Prom./PV"
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1555,7 +1555,7 @@ msgstr "Diariamente a las %{time}"
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr "Panel"
 
@@ -2788,11 +2788,11 @@ msgstr "Archivo subido correctamente"
 msgid "Filename is empty"
 msgstr "El nombre del archivo está vacío"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr "Filtro"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr "Filtrar contenido del registro"
 
@@ -4122,7 +4122,7 @@ msgstr "Nginx no se está ejecutando en otro contenedor"
 msgid "Nginx is running"
 msgstr "Nginx está en ejecución"
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr "Registro Nginx"
 
@@ -5045,7 +5045,7 @@ msgstr "En cola para indexación..."
 msgid "Quick Select"
 msgstr "Selección rápida"
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr "Crudo"
 
@@ -6176,7 +6176,7 @@ msgstr "El directorio streams-available no existe"
 msgid "Streams-enabled directory not exist"
 msgstr "El directorio streams-enabled no existe"
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr "Estructurado"
 
@@ -7300,7 +7300,7 @@ msgstr "Escribir certificado a disco"
 msgid "Yes"
 msgstr "Si"
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 9 - 9
app/src/language/fr_FR/app.po

@@ -503,7 +503,7 @@ msgstr "Échec de la sauvegarde automatique"
 msgid "Auto Backup Storage Failed"
 msgstr "Échec du stockage de sauvegarde automatique"
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr "Actualisation automatique"
 
@@ -555,7 +555,7 @@ msgstr "Moy./PV"
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1561,7 +1561,7 @@ msgstr "Quotidiennement à %{time}"
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr "Dashboard"
 
@@ -2794,11 +2794,11 @@ msgstr "Fichier téléchargé avec succès"
 msgid "Filename is empty"
 msgstr "Nom du fichier vide"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr "Filtrer"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr "Filtrer le contenu du journal"
 
@@ -4132,7 +4132,7 @@ msgstr "Nginx ne fonctionne pas dans un autre conteneur"
 msgid "Nginx is running"
 msgstr "Nginx est en cours d'exécution"
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr "Journal Nginx"
 
@@ -5055,7 +5055,7 @@ msgstr "En attente d'indexation..."
 msgid "Quick Select"
 msgstr "Sélection rapide"
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr "Brut"
 
@@ -6186,7 +6186,7 @@ msgstr "Le répertoire streams-available n'existe pas"
 msgid "Streams-enabled directory not exist"
 msgstr "Le répertoire streams-enabled n'existe pas"
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr "Structuré"
 
@@ -7325,7 +7325,7 @@ msgstr "Écriture du certificat sur le disque"
 msgid "Yes"
 msgstr "Oui"
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 9 - 9
app/src/language/ja_JP/app.po

@@ -489,7 +489,7 @@ msgstr "自動バックアップが失敗しました"
 msgid "Auto Backup Storage Failed"
 msgstr "自動バックアップの保存に失敗しました"
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr "自動更新"
 
@@ -541,7 +541,7 @@ msgstr "平均/PV"
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1526,7 +1526,7 @@ msgstr "毎日 %{time}"
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr "ダッシュボード"
 
@@ -2750,11 +2750,11 @@ msgstr "ファイルが正常にアップロードされました"
 msgid "Filename is empty"
 msgstr "ファイル名が空です"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr "フィルター"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr "ログ内容をフィルタリング"
 
@@ -4080,7 +4080,7 @@ msgstr "Nginx は他のコンテナで実行されていません"
 msgid "Nginx is running"
 msgstr "Nginx は実行中です"
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr "Nginx ログ"
 
@@ -4980,7 +4980,7 @@ msgstr "インデックス作成待ち..."
 msgid "Quick Select"
 msgstr "クイック選択"
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr "生"
 
@@ -6101,7 +6101,7 @@ msgstr "streams-available ディレクトリが存在しません"
 msgid "Streams-enabled directory not exist"
 msgstr "streams-enabled ディレクトリが存在しません"
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr "構造化"
 
@@ -7213,7 +7213,7 @@ msgstr "証明書をディスクに書き込み中"
 msgid "Yes"
 msgstr "はい"
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 9 - 9
app/src/language/ko_KR/app.po

@@ -483,7 +483,7 @@ msgstr "자동 백업 실패"
 msgid "Auto Backup Storage Failed"
 msgstr "자동 백업 저장 실패"
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr "자동 새로고침"
 
@@ -535,7 +535,7 @@ msgstr "평균/PV"
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1506,7 +1506,7 @@ msgstr "매일 %{time}"
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr "대시보드"
 
@@ -2726,11 +2726,11 @@ msgstr "파일이 성공적으로 업로드되었습니다"
 msgid "Filename is empty"
 msgstr "파일 이름이 비어 있습니다"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr "필터"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr "로그 내용 필터링"
 
@@ -4045,7 +4045,7 @@ msgstr "Nginx가 다른 컨테이너에서 실행되고 있지 않습니다"
 msgid "Nginx is running"
 msgstr "Nginx가 실행 중입니다"
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr "Nginx 로그"
 
@@ -4938,7 +4938,7 @@ msgstr "인덱싱 대기 중..."
 msgid "Quick Select"
 msgstr "빠른 선택"
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr "원시"
 
@@ -6058,7 +6058,7 @@ msgstr "streams-available 디렉터리가 존재하지 않습니다"
 msgid "Streams-enabled directory not exist"
 msgstr "streams-enabled 디렉터리가 존재하지 않습니다"
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr "구조화된"
 
@@ -7160,7 +7160,7 @@ msgstr "인증서를 디스크에 쓰기"
 msgid "Yes"
 msgstr "예"
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 9 - 9
app/src/language/messages.pot

@@ -468,7 +468,7 @@ msgstr ""
 msgid "Auto Backup Storage Failed"
 msgstr ""
 
-#: src/views/nginx_log/NginxLog.vue:64
+#: src/views/nginx_log/NginxLog.vue:86
 #: src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr ""
@@ -522,7 +522,7 @@ msgstr ""
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120
 #: src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1423,7 +1423,7 @@ msgstr ""
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
 #: src/views/config/ConfigList.vue:69
-#: src/views/nginx_log/NginxLog.vue:56
+#: src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr ""
 
@@ -2634,11 +2634,11 @@ msgstr ""
 msgid "Filename is empty"
 msgstr ""
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr ""
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr ""
 
@@ -3914,7 +3914,7 @@ msgid "Nginx is running"
 msgstr ""
 
 #: src/routes/modules/nginx_log.ts:9
-#: src/views/nginx_log/NginxLog.vue:39
+#: src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr ""
 
@@ -4781,7 +4781,7 @@ msgstr ""
 msgid "Quick Select"
 msgstr ""
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr ""
 
@@ -5873,7 +5873,7 @@ msgstr ""
 msgid "Streams-enabled directory not exist"
 msgstr ""
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr ""
 
@@ -6852,7 +6852,7 @@ msgstr ""
 msgid "Yes"
 msgstr ""
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid "You are accessing this terminal over an insecure HTTP connection on a non-localhost domain. This may expose sensitive information."
 msgstr ""
 

+ 9 - 9
app/src/language/pt_PT/app.po

@@ -495,7 +495,7 @@ msgstr "Backup automático falhou"
 msgid "Auto Backup Storage Failed"
 msgstr "Falha no armazenamento de backup automático"
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr "Actualizar Automaticamente"
 
@@ -547,7 +547,7 @@ msgstr "Méd./PV"
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1543,7 +1543,7 @@ msgstr "Diariamente às %{time}"
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr "Painel"
 
@@ -2769,11 +2769,11 @@ msgstr "Ficheiro carregado com sucesso"
 msgid "Filename is empty"
 msgstr "O nome do ficheiro está vazio"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr "Filtro"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr "Filtrar conteúdo do registo"
 
@@ -4103,7 +4103,7 @@ msgstr "O Nginx não está em execução noutro contentor"
 msgid "Nginx is running"
 msgstr "O Nginx está em execução"
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr "Logs do Nginx"
 
@@ -5022,7 +5022,7 @@ msgstr "Na fila para indexação..."
 msgid "Quick Select"
 msgstr "Seleção rápida"
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr "Bruto"
 
@@ -6149,7 +6149,7 @@ msgstr "O diretório streams-available não existe"
 msgid "Streams-enabled directory not exist"
 msgstr "O diretório streams-enabled não existe"
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr "Estruturado"
 
@@ -7273,7 +7273,7 @@ msgstr "Escrevendo certificado no disco"
 msgid "Yes"
 msgstr "Sim"
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 9 - 9
app/src/language/ru_RU/app.po

@@ -496,7 +496,7 @@ msgstr "Автоматическое резервное копирование 
 msgid "Auto Backup Storage Failed"
 msgstr "Сбой хранения автоматической резервной копии"
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr "Автообновление"
 
@@ -548,7 +548,7 @@ msgstr "Сред./PV"
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1543,7 +1543,7 @@ msgstr "Ежедневно в %{time}"
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr "Доска"
 
@@ -2770,11 +2770,11 @@ msgstr "Файл успешно загружен"
 msgid "Filename is empty"
 msgstr "Имя файла пустое"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr "Фильтр"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr "Фильтровать содержимое журнала"
 
@@ -4101,7 +4101,7 @@ msgstr "Nginx не работает в другом контейнере"
 msgid "Nginx is running"
 msgstr "Nginx работает"
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr "Журнал"
 
@@ -5021,7 +5021,7 @@ msgstr "В очереди на индексацию..."
 msgid "Quick Select"
 msgstr "Быстрый выбор"
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr "Сырой"
 
@@ -6144,7 +6144,7 @@ msgstr "Каталог streams-available не существует"
 msgid "Streams-enabled directory not exist"
 msgstr "Каталог streams-enabled не существует"
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr "Структурированный"
 
@@ -7260,7 +7260,7 @@ msgstr "Запись сертификата на диск"
 msgid "Yes"
 msgstr "Да"
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 9 - 9
app/src/language/tr_TR/app.po

@@ -498,7 +498,7 @@ msgstr "Otomatik Yedekleme Başarısız"
 msgid "Auto Backup Storage Failed"
 msgstr "Otomatik Yedekleme Depolama Başarısız"
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr "Otomatik Yenileme"
 
@@ -550,7 +550,7 @@ msgstr "Ort./PV"
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1541,7 +1541,7 @@ msgstr "Günlük olarak saat %{time}"
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr "Kontrol Paneli"
 
@@ -2770,11 +2770,11 @@ msgstr "Dosya başarıyla yüklendi"
 msgid "Filename is empty"
 msgstr "Dosya adı boş"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr "Filtre"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr "Günlük içeriğini filtrele"
 
@@ -4103,7 +4103,7 @@ msgstr "Nginx başka bir konteynerde çalışmıyor"
 msgid "Nginx is running"
 msgstr "Nginx çalışıyor"
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr "Nginx Günlüğü"
 
@@ -5015,7 +5015,7 @@ msgstr "Dizine ekleme için sırada..."
 msgid "Quick Select"
 msgstr "Hızlı Seçim"
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr "Ham"
 
@@ -6147,7 +6147,7 @@ msgstr "Streams-available dizini mevcut değil"
 msgid "Streams-enabled directory not exist"
 msgstr "Streams-enabled dizini mevcut değil"
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr "Yapılandırılmış"
 
@@ -7265,7 +7265,7 @@ msgstr "Sertifika diske yazılıyor"
 msgid "Yes"
 msgstr "Evet"
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 9 - 9
app/src/language/uk_UA/app.po

@@ -497,7 +497,7 @@ msgstr "Автоматичне резервне копіювання не вда
 msgid "Auto Backup Storage Failed"
 msgstr "Не вдалося зберегти автоматичну резервну копію"
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr "Автоматичне оновлення"
 
@@ -549,7 +549,7 @@ msgstr "Середн./PV"
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1579,7 +1579,7 @@ msgstr "Щодня о %{time}"
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr "Панель керування"
 
@@ -2842,11 +2842,11 @@ msgstr "Файл успішно завантажено"
 msgid "Filename is empty"
 msgstr "Назва файлу порожня"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr "Фільтр"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr "Фільтрувати вміст журналу"
 
@@ -4172,7 +4172,7 @@ msgstr "Nginx не працює в іншому контейнері"
 msgid "Nginx is running"
 msgstr "Nginx працює"
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr "Nginx Журнал"
 
@@ -5088,7 +5088,7 @@ msgstr "У черзі на індексацію..."
 msgid "Quick Select"
 msgstr "Швидкий вибір"
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr "Сирий"
 
@@ -6216,7 +6216,7 @@ msgstr "Каталог Streams-available не існує"
 msgid "Streams-enabled directory not exist"
 msgstr "Каталог streams-enabled не існує"
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr "Структурований"
 
@@ -7330,7 +7330,7 @@ msgstr "Запис сертифіката на диск"
 msgid "Yes"
 msgstr "Так"
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 9 - 9
app/src/language/vi_VN/app.po

@@ -484,7 +484,7 @@ msgstr "Sao lưu tự động thất bại"
 msgid "Auto Backup Storage Failed"
 msgstr "Lưu trữ sao lưu tự động thất bại"
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr "Tự động làm mới"
 
@@ -536,7 +536,7 @@ msgstr "TB/PV"
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1517,7 +1517,7 @@ msgstr "Hàng ngày lúc %{time}"
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr "Bảng điều khiển"
 
@@ -2741,11 +2741,11 @@ msgstr "Tải lên tệp thành công"
 msgid "Filename is empty"
 msgstr "Tên tệp trống"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr "Lọc"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr "Lọc nội dung nhật ký"
 
@@ -4068,7 +4068,7 @@ msgstr "Nginx không chạy trong một container khác"
 msgid "Nginx is running"
 msgstr "Nginx đang chạy"
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr "Nhật ký Nginx"
 
@@ -4971,7 +4971,7 @@ msgstr "Đang xếp hàng để lập chỉ mục..."
 msgid "Quick Select"
 msgstr "Chọn nhanh"
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr "Thô"
 
@@ -6091,7 +6091,7 @@ msgstr "Thư mục Streams-available không tồn tại"
 msgid "Streams-enabled directory not exist"
 msgstr "Thư mục streams-enabled không tồn tại"
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr "Có cấu trúc"
 
@@ -7202,7 +7202,7 @@ msgstr "Ghi chứng chỉ vào disk"
 msgid "Yes"
 msgstr "Có"
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 9 - 9
app/src/language/zh_CN/app.po

@@ -480,7 +480,7 @@ msgstr "自动备份失败"
 msgid "Auto Backup Storage Failed"
 msgstr "自动备份存储失败"
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr "自动刷新"
 
@@ -532,7 +532,7 @@ msgstr "平均/PV"
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1492,7 +1492,7 @@ msgstr "每天 %{time}"
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr "仪表盘"
 
@@ -2707,11 +2707,11 @@ msgstr "文件上传成功"
 msgid "Filename is empty"
 msgstr "文件名为空"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr "过滤"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr "过滤日志内容"
 
@@ -4016,7 +4016,7 @@ msgstr "Nginx 未在另一个容器中运行"
 msgid "Nginx is running"
 msgstr "Nginx 正在运行"
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr "Nginx 日志"
 
@@ -4903,7 +4903,7 @@ msgstr "排队等待索引中..."
 msgid "Quick Select"
 msgstr "快速选择"
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr "原始"
 
@@ -6008,7 +6008,7 @@ msgstr "Streams-available 目录不存在"
 msgid "Streams-enabled directory not exist"
 msgstr "Streams-enabled 目录不存在"
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr "结构化"
 
@@ -7071,7 +7071,7 @@ msgstr "正在将证书写入磁盘"
 msgid "Yes"
 msgstr "是的"
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 9 - 9
app/src/language/zh_TW/app.po

@@ -484,7 +484,7 @@ msgstr "自動備份失敗"
 msgid "Auto Backup Storage Failed"
 msgstr "自動備份儲存失敗"
 
-#: src/views/nginx_log/NginxLog.vue:64 src/views/node/Node.vue:164
+#: src/views/nginx_log/NginxLog.vue:86 src/views/node/Node.vue:164
 msgid "Auto Refresh"
 msgstr "自動重新整理"
 
@@ -536,7 +536,7 @@ msgstr "平均 /PV"
 #: src/views/certificate/components/CertificateActions.vue:22
 #: src/views/config/components/ConfigLeftPanel.vue:273
 #: src/views/config/ConfigList.vue:120 src/views/config/ConfigList.vue:217
-#: src/views/nginx_log/NginxLog.vue:92
+#: src/views/nginx_log/NginxLog.vue:114
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:170
 #: src/views/stream/components/StreamEditor.vue:134
 msgid "Back"
@@ -1497,7 +1497,7 @@ msgstr "每天 %{time}"
 #: src/routes/modules/dashboard.ts:10
 #: src/views/config/components/ConfigLeftPanel.vue:109
 #: src/views/config/components/ConfigLeftPanel.vue:159
-#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:56
+#: src/views/config/ConfigList.vue:69 src/views/nginx_log/NginxLog.vue:78
 msgid "Dashboard"
 msgstr "儀錶板"
 
@@ -2712,11 +2712,11 @@ msgstr "檔案上傳成功"
 msgid "Filename is empty"
 msgstr "檔名空白"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:155
+#: src/views/nginx_log/raw/RawLogViewer.vue:298
 msgid "Filter"
 msgstr "篩選"
 
-#: src/views/nginx_log/raw/RawLogViewer.vue:158
+#: src/views/nginx_log/raw/RawLogViewer.vue:301
 msgid "Filter log content"
 msgstr "過濾日誌內容"
 
@@ -4020,7 +4020,7 @@ msgstr "Nginx 未在另一個容器中運行"
 msgid "Nginx is running"
 msgstr "Nginx 執行中"
 
-#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:39
+#: src/routes/modules/nginx_log.ts:9 src/views/nginx_log/NginxLog.vue:61
 msgid "Nginx Log"
 msgstr "Nginx 日誌"
 
@@ -4907,7 +4907,7 @@ msgstr "排隊等待索引中..."
 msgid "Quick Select"
 msgstr "快速選擇"
 
-#: src/views/nginx_log/NginxLog.vue:57
+#: src/views/nginx_log/NginxLog.vue:79
 msgid "Raw"
 msgstr "原始"
 
@@ -6011,7 +6011,7 @@ msgstr "streams-available 資料夾不存在"
 msgid "Streams-enabled directory not exist"
 msgstr "streams-enabled 資料夾不存在"
 
-#: src/views/nginx_log/NginxLog.vue:55
+#: src/views/nginx_log/NginxLog.vue:77
 msgid "Structured"
 msgstr "結構化"
 
@@ -7076,7 +7076,7 @@ msgstr "將憑證寫入磁碟"
 msgid "Yes"
 msgstr "是的"
 
-#: src/views/terminal/Terminal.vue:201
+#: src/views/terminal/Terminal.vue:200
 msgid ""
 "You are accessing this terminal over an insecure HTTP connection on a non-"
 "localhost domain. This may expose sensitive information."

+ 15 - 15
internal/cache/index.go

@@ -133,19 +133,19 @@ func (s *Scanner) Initialize(ctx context.Context) error {
 
 	// Start background processes with WaitGroup tracking
 	s.wg.Go(func() {
-		logger.Info("Started cache watchForChanges goroutine")
+		logger.Debug("Started cache watchForChanges goroutine")
 		s.watchForChanges()
 		logger.Info("Cache watchForChanges goroutine completed")
 	})
 
 	s.wg.Go(func() {
-		logger.Info("Started cache periodicScan goroutine")
+		logger.Debug("Started cache periodicScan goroutine")
 		s.periodicScan()
 		logger.Info("Cache periodicScan goroutine completed")
 	})
 
 	s.wg.Go(func() {
-		logger.Info("Started cache handleShutdown goroutine")
+		logger.Debug("Started cache handleShutdown goroutine")
 		s.handleShutdown()
 		logger.Info("Cache handleShutdown goroutine completed")
 	})
@@ -153,9 +153,9 @@ func (s *Scanner) Initialize(ctx context.Context) error {
 	// Perform initial scan asynchronously to avoid blocking boot process
 	// Pass the context to ensure proper cancellation
 	s.wg.Go(func() {
-		logger.Info("Started cache initialScanAsync goroutine")
+		logger.Debug("Started cache initialScanAsync goroutine")
 		s.initialScanAsync(ctx)
-		logger.Info("Cache initialScanAsync goroutine completed")
+		logger.Debug("Cache initialScanAsync goroutine completed")
 	})
 
 	return nil
@@ -219,7 +219,7 @@ func (s *Scanner) periodicScan() {
 // handleShutdown listens for context cancellation and shuts down gracefully
 func (s *Scanner) handleShutdown() {
 	<-s.ctx.Done()
-	logger.Info("Shutting down Index Scanner")
+	logger.Debug("Shutting down Index Scanner")
 	// Note: Don't call s.Shutdown() here as it would cause deadlock
 	// Shutdown is called externally, this just handles cleanup
 }
@@ -243,8 +243,8 @@ func (s *Scanner) initialScanAsync(ctx context.Context) {
 	default:
 	}
 
-	logger.Info("Starting initial config scan...")
-	logger.Infof("Config path: %s", nginx.GetConfPath())
+	logger.Debug("Starting initial config scan...")
+	logger.Debugf("Config path: %s", nginx.GetConfPath())
 
 	// Perform the scan with the fresh context (not scanner's internal context)
 	if err := s.scanAllConfigsWithContext(ctx); err != nil {
@@ -252,7 +252,7 @@ func (s *Scanner) initialScanAsync(ctx context.Context) {
 		if ctx.Err() == nil {
 			logger.Errorf("Initial config scan failed: %v", err)
 		} else {
-			logger.Infof("Initial config scan cancelled due to context: %v", ctx.Err())
+			logger.Debugf("Initial config scan cancelled due to context: %v", ctx.Err())
 		}
 		// Signal completion even on error so waiting services don't hang
 		initialScanOnce.Do(func() {
@@ -263,7 +263,7 @@ func (s *Scanner) initialScanAsync(ctx context.Context) {
 		// Signal that initial scan is complete - this allows other services to proceed
 		// that depend on the scan callbacks to have been processed
 		initialScanOnce.Do(func() {
-			logger.Info("Initial config scan and callbacks completed - signaling completion")
+			logger.Debug("Initial config scan and callbacks completed - signaling completion")
 			close(initialScanComplete)
 		})
 	}
@@ -275,14 +275,14 @@ func (s *Scanner) scanAllConfigsWithContext(ctx context.Context) error {
 	defer s.setScanningState(false)
 
 	root := nginx.GetConfPath()
-	logger.Infof("Scanning config directory: %s", root)
+	logger.Debugf("Scanning config directory: %s", root)
 
 	// Create a timeout context for the scan operation
 	scanCtx, scanCancel := context.WithTimeout(ctx, 15*time.Second)
 	defer scanCancel()
 
 	// Scan all files in the config directory and subdirectories
-	logger.Info("Starting filepath.WalkDir scanning...")
+	logger.Debug("Starting filepath.WalkDir scanning...")
 
 	// Use a channel to communicate scan results
 	type scanResult struct {
@@ -311,7 +311,7 @@ func (s *Scanner) scanAllConfigsWithContext(ctx context.Context) error {
 	// Wait for scan to complete or timeout
 	select {
 	case result := <-resultChan:
-		logger.Infof("Scan completed successfully: dirs=%d, files=%d, error=%v",
+		logger.Debugf("Scan completed successfully: dirs=%d, files=%d, error=%v",
 			result.dirCount, result.fileCount, result.err)
 		return result.err
 	case <-scanCtx.Done():
@@ -320,7 +320,7 @@ func (s *Scanner) scanAllConfigsWithContext(ctx context.Context) error {
 		// Wait a bit more for cleanup
 		select {
 		case result := <-resultChan:
-			logger.Infof("Scan completed after timeout: dirs=%d, files=%d, error=%v",
+			logger.Debugf("Scan completed after timeout: dirs=%d, files=%d, error=%v",
 				result.dirCount, result.fileCount, result.err)
 			return result.err
 		case <-time.After(2 * time.Second):
@@ -807,7 +807,7 @@ func WaitForInitialScanComplete() {
 	// Add timeout to prevent infinite waiting
 	select {
 	case <-initialScanComplete:
-		logger.Info("Initial config scan completion confirmed")
+		logger.Debug("Initial config scan completion confirmed")
 	case <-time.After(30 * time.Second):
 		logger.Warn("Timeout waiting for initial config scan completion - proceeding anyway")
 	}

+ 2 - 2
internal/event/bus.go

@@ -42,7 +42,7 @@ func (eb *Bus) SetWebSocketHub(hub WebSocketHub) {
 	eb.wsMutex.Lock()
 	defer eb.wsMutex.Unlock()
 	eb.wsHub = hub
-	logger.Info("WebSocket hub registered with event bus")
+	logger.Debug("WebSocket hub registered with event bus")
 }
 
 // Publish forwards an event directly to WebSocket clients
@@ -66,7 +66,7 @@ func (eb *Bus) Shutdown() {
 	defer eb.wsMutex.Unlock()
 
 	eb.wsHub = nil
-	logger.Info("Event bus shutdown completed")
+	logger.Debug("Event bus shutdown completed")
 }
 
 // Context returns the event bus context

+ 1 - 1
internal/event/processing_status.go

@@ -95,7 +95,7 @@ func (m *ProcessingStatusManager) BroadcastCurrentStatus() {
 	m.mu.RLock()
 	defer m.mu.RUnlock()
 
-	logger.Info("Broadcasting current processing status to new client")
+	logger.Debug("Broadcasting current processing status to new client")
 	Publish(Event{
 		Type: TypeProcessingStatus,
 		Data: m.status,

+ 31 - 1
internal/nginx_log/indexer/adaptive_optimization.go

@@ -202,6 +202,10 @@ func (ao *AdaptiveOptimizer) cpuMonitoringLoop() {
 
 // measureAndAdjustCPU measures current CPU utilization and suggests adjustments
 func (ao *AdaptiveOptimizer) measureAndAdjustCPU() {
+	// Only adjust when indexer is actively processing
+	if !ao.isIndexerBusy() {
+		return
+	}
 	// Get current CPU utilization
 	cpuUsage := ao.getCurrentCPUUtilization()
 
@@ -258,6 +262,10 @@ func (ao *AdaptiveOptimizer) batchOptimizationLoop() {
 
 // optimizeBatchSize analyzes performance and adjusts batch size
 func (ao *AdaptiveOptimizer) optimizeBatchSize() {
+	// Only adjust when indexer is actively processing
+	if !ao.isIndexerBusy() {
+		return
+	}
 	ao.performanceHistory.mutex.RLock()
 	if len(ao.performanceHistory.samples) < 5 {
 		ao.performanceHistory.mutex.RUnlock()
@@ -302,6 +310,10 @@ func (ao *AdaptiveOptimizer) calculateOptimalBatchSize(throughput float64, laten
 
 // adjustBatchSize applies the batch size adjustment
 func (ao *AdaptiveOptimizer) adjustBatchSize(oldSize, newSize int, throughput float64, latency time.Duration) {
+	// Only adjust when indexer is actively processing
+	if !ao.isIndexerBusy() {
+		return
+	}
 	atomic.StoreInt32(&ao.batchSizeController.currentBatchSize, int32(newSize))
 
 	var reason string
@@ -329,7 +341,7 @@ func (ao *AdaptiveOptimizer) adjustBatchSize(oldSize, newSize int, throughput fl
 	}
 	ao.batchSizeController.historyMutex.Unlock()
 
-	logger.Infof("Batch size adjusted: old_size=%d, new_size=%d, reason=%s", oldSize, newSize, reason)
+	logger.Debugf("Batch size adjusted: old_size=%d, new_size=%d, reason=%s", oldSize, newSize, reason)
 }
 
 // performanceTrackingLoop continuously tracks performance metrics
@@ -544,6 +556,10 @@ func (ao *AdaptiveOptimizer) suggestWorkerIncrease(currentCPU, targetCPU float64
 }
 
 func (ao *AdaptiveOptimizer) suggestWorkerDecrease(currentCPU, targetCPU float64) {
+	// If the indexer is not busy, don't adjust workers
+	if !ao.isIndexerBusy() {
+		return
+	}
 	// If already at min workers, do nothing.
 	currentWorkers := int(atomic.LoadInt64(&ao.workerCount))
 	if currentWorkers <= ao.cpuMonitor.minWorkers {
@@ -580,6 +596,11 @@ func (ao *AdaptiveOptimizer) suggestWorkerDecrease(currentCPU, targetCPU float64
 
 // adjustWorkerCount dynamically adjusts the worker count at runtime
 func (ao *AdaptiveOptimizer) adjustWorkerCount(newCount int) {
+	// Only adjust when indexer is actively processing
+	if !ao.isIndexerBusy() {
+		logger.Debugf("Skipping worker adjustment while idle: requested=%d", newCount)
+		return
+	}
 	oldCount := int(atomic.LoadInt64(&ao.workerCount))
 	if newCount <= 0 || newCount == oldCount {
 		logger.Debugf("Skipping worker adjustment: newCount=%d, currentCount=%d", newCount, oldCount)
@@ -619,3 +640,12 @@ func min(a, b int) int {
 	}
 	return b
 }
+
+// isIndexerBusy reports whether the indexer is currently processing work.
+// When no poller is configured, it returns false to avoid unintended adjustments.
+func (ao *AdaptiveOptimizer) isIndexerBusy() bool {
+	if ao.activityPoller == nil {
+		return false
+	}
+	return ao.activityPoller.IsBusy()
+}

+ 191 - 18
internal/nginx_log/modern_services.go

@@ -5,6 +5,9 @@ import (
 	"fmt"
 	"os"
 	"path/filepath"
+	"regexp"
+	"sort"
+	"strings"
 	"sync"
 	"sync/atomic"
 	"time"
@@ -31,6 +34,12 @@ var (
 	lastShardUpdateAttempt int64
 )
 
+// Fallback storage when AdvancedIndexingEnabled is disabled
+var (
+	fallbackCache      = make(map[string]*NginxLogCache)
+	fallbackCacheMutex sync.RWMutex
+)
+
 // InitializeModernServices initializes the new modular services
 func InitializeModernServices(ctx context.Context) {
 	servicesMutex.Lock()
@@ -229,23 +238,37 @@ const (
 
 // AddLogPath adds a log path to the log cache with the source config file
 func AddLogPath(path, logType, name, configFile string) {
-	manager := GetLogFileManager()
-	if manager != nil {
+	if manager := GetLogFileManager(); manager != nil {
 		manager.AddLogPath(path, logType, name, configFile)
-	} else {
-		// Only warn if during initialization (when it might be expected)
-		// Skip warning during shutdown or restart phases
+		return
+	}
+
+	// Fallback storage
+	fallbackCacheMutex.Lock()
+	fallbackCache[path] = &NginxLogCache{
+		Path:       path,
+		Type:       logType,
+		Name:       name,
+		ConfigFile: configFile,
 	}
+	fallbackCacheMutex.Unlock()
 }
 
 // RemoveLogPathsFromConfig removes all log paths associated with a specific config file
 func RemoveLogPathsFromConfig(configFile string) {
-	manager := GetLogFileManager()
-	if manager != nil {
+	if manager := GetLogFileManager(); manager != nil {
 		manager.RemoveLogPathsFromConfig(configFile)
-	} else {
-		// Silently skip if manager not available - this is normal during shutdown/restart
+		return
 	}
+
+	// Fallback removal
+	fallbackCacheMutex.Lock()
+	for p, entry := range fallbackCache {
+		if entry.ConfigFile == configFile {
+			delete(fallbackCache, p)
+		}
+	}
+	fallbackCacheMutex.Unlock()
 }
 
 // GetAllLogPaths returns all cached log paths, optionally filtered
@@ -253,7 +276,27 @@ func GetAllLogPaths(filters ...func(*NginxLogCache) bool) []*NginxLogCache {
 	if manager := GetLogFileManager(); manager != nil {
 		return manager.GetAllLogPaths(filters...)
 	}
-	return []*NginxLogCache{}
+
+	// Fallback list
+	fallbackCacheMutex.RLock()
+	defer fallbackCacheMutex.RUnlock()
+
+	var logs []*NginxLogCache
+	for _, entry := range fallbackCache {
+		include := true
+		for _, f := range filters {
+			if !f(entry) {
+				include = false
+				break
+			}
+		}
+		if include {
+			// Create a copy to avoid external mutation
+			e := *entry
+			logs = append(logs, &e)
+		}
+	}
+	return logs
 }
 
 // GetAllLogsWithIndex returns all cached log paths with their index status
@@ -261,7 +304,33 @@ func GetAllLogsWithIndex(filters ...func(*NginxLogWithIndex) bool) []*NginxLogWi
 	if manager := GetLogFileManager(); manager != nil {
 		return manager.GetAllLogsWithIndex(filters...)
 	}
-	return []*NginxLogWithIndex{}
+
+	// Fallback: produce basic entries without indexing metadata
+	fallbackCacheMutex.RLock()
+	defer fallbackCacheMutex.RUnlock()
+
+	result := make([]*NginxLogWithIndex, 0, len(fallbackCache))
+	for _, c := range fallbackCache {
+		lw := &NginxLogWithIndex{
+			Path:        c.Path,
+			Type:        c.Type,
+			Name:        c.Name,
+			ConfigFile:  c.ConfigFile,
+			IndexStatus: IndexStatusNotIndexed,
+		}
+
+		include := true
+		for _, f := range filters {
+			if !f(lw) {
+				include = false
+				break
+			}
+		}
+		if include {
+			result = append(result, lw)
+		}
+	}
+	return result
 }
 
 // GetAllLogsWithIndexGrouped returns logs grouped by their base name
@@ -269,7 +338,112 @@ func GetAllLogsWithIndexGrouped(filters ...func(*NginxLogWithIndex) bool) []*Ngi
 	if manager := GetLogFileManager(); manager != nil {
 		return manager.GetAllLogsWithIndexGrouped(filters...)
 	}
-	return []*NginxLogWithIndex{}
+
+	// Fallback grouping by base log name (handle simple rotation patterns)
+	fallbackCacheMutex.RLock()
+	defer fallbackCacheMutex.RUnlock()
+
+	grouped := make(map[string]*NginxLogWithIndex)
+	for _, c := range fallbackCache {
+		base := getBaseLogNameBasic(c.Path)
+		if existing, ok := grouped[base]; ok {
+			// Preserve most recent non-indexed default; nothing to aggregate in basic mode
+			_ = existing
+			continue
+		}
+		grouped[base] = &NginxLogWithIndex{
+			Path:        base,
+			Type:        c.Type,
+			Name:        filepath.Base(base),
+			ConfigFile:  c.ConfigFile,
+			IndexStatus: IndexStatusNotIndexed,
+		}
+	}
+
+	// Build slice and apply filters
+	keys := make([]string, 0, len(grouped))
+	for k := range grouped {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+
+	result := make([]*NginxLogWithIndex, 0, len(keys))
+	for _, k := range keys {
+		v := grouped[k]
+		include := true
+		for _, f := range filters {
+			if !f(v) {
+				include = false
+				break
+			}
+		}
+		if include {
+			result = append(result, v)
+		}
+	}
+	return result
+}
+
+// --- Fallback helpers ---
+
+// getBaseLogNameBasic attempts to derive the base log file for a rotated file name.
+// Mirrors the logic used by the indexer, simplified for basic mode.
+func getBaseLogNameBasic(filePath string) string {
+	dir := filepath.Dir(filePath)
+	filename := filepath.Base(filePath)
+
+	// Remove compression extensions
+	for _, ext := range []string{".gz", ".bz2", ".xz", ".lz4"} {
+		filename = strings.TrimSuffix(filename, ext)
+	}
+
+	// Check YYYY.MM.DD at end
+	parts := strings.Split(filename, ".")
+	if len(parts) >= 4 {
+		lastThree := strings.Join(parts[len(parts)-3:], ".")
+		if matched, _ := regexp.MatchString(`^\d{4}\.\d{2}\.\d{2}$`, lastThree); matched {
+			base := strings.Join(parts[:len(parts)-3], ".")
+			return filepath.Join(dir, base)
+		}
+	}
+
+	// Single-part date suffix (YYYYMMDD / YYYY-MM-DD / YYMMDD)
+	if len(parts) >= 2 {
+		last := parts[len(parts)-1]
+		if isFullDatePatternBasic(last) {
+			base := strings.Join(parts[:len(parts)-1], ".")
+			return filepath.Join(dir, base)
+		}
+	}
+
+	// Numbered rotation: access.log.1
+	if m := regexp.MustCompile(`^(.+)\.(\d{1,3})$`).FindStringSubmatch(filename); len(m) > 1 {
+		base := m[1]
+		return filepath.Join(dir, base)
+	}
+
+	// Middle-numbered rotation: access.1.log
+	if m := regexp.MustCompile(`^(.+)\.(\d{1,3})\.log$`).FindStringSubmatch(filename); len(m) > 1 {
+		base := m[1] + ".log"
+		return filepath.Join(dir, base)
+	}
+
+	// Fallback: return original path
+	return filePath
+}
+
+func isFullDatePatternBasic(s string) bool {
+	patterns := []string{
+		`^\d{8}$`,             // YYYYMMDD
+		`^\d{4}-\d{2}-\d{2}$`, // YYYY-MM-DD
+		`^\d{6}$`,             // YYMMDD
+	}
+	for _, p := range patterns {
+		if matched, _ := regexp.MatchString(p, s); matched {
+			return true
+		}
+	}
+	return false
 }
 
 // SetIndexingStatus sets the indexing status for a specific file path
@@ -375,7 +549,6 @@ func updateSearcherShardsLocked() {
 	} else {
 		logger.Warn("globalSearcher is not a DistributedSearcher, cannot perform hot-swap")
 	}
-
 }
 
 // StopModernServices stops all running modern services
@@ -384,16 +557,16 @@ func StopModernServices() {
 	defer servicesMutex.Unlock()
 
 	if !servicesInitialized {
-		logger.Info("Modern nginx log services not initialized, nothing to stop")
+		logger.Debug("Modern nginx log services not initialized, nothing to stop")
 		return
 	}
 
 	if isShuttingDown {
-		logger.Info("Modern nginx log services already shutting down")
+		logger.Debug("Modern nginx log services already shutting down")
 		return
 	}
 
-	logger.Info("Stopping modern nginx log services...")
+	logger.Debug("Stopping modern nginx log services...")
 	isShuttingDown = true
 
 	// Cancel the service context to trigger graceful shutdown
@@ -431,7 +604,7 @@ func StopModernServices() {
 	shutdownCancel = nil
 	isShuttingDown = false
 
-	logger.Info("Modern nginx log services stopped")
+	logger.Debug("Modern nginx log services stopped")
 }
 
 // DestroyAllIndexes completely removes all indexed data from disk.
@@ -440,7 +613,7 @@ func DestroyAllIndexes(ctx context.Context) error {
 	defer servicesMutex.RUnlock()
 
 	if !servicesInitialized || globalIndexer == nil {
-		logger.Warn("Cannot destroy indexes, services not initialized.")
+		logger.Debug("Cannot destroy indexes, services not initialized.")
 		return fmt.Errorf("services not initialized")
 	}
 

+ 0 - 5
internal/nginx_log/nginx_log.go

@@ -131,8 +131,3 @@ func isCommentedMatch(content []byte, match [][]byte) bool {
 
 	return false
 }
-
-// GetAllLogs returns all log paths
-func GetAllLogs(filters ...func(*NginxLogCache) bool) []*NginxLogCache {
-	return GetAllLogPaths(filters...)
-}

+ 2 - 15
internal/nginx_log/searcher/distributed_searcher.go

@@ -519,22 +519,9 @@ func (ds *DistributedSearcher) SwapShards(newShards []bleve.Index) error {
 	}
 	ds.stats.mutex.Unlock()
 
-	logger.Infof("IndexAlias.Swap() completed: %d old shards -> %d new shards",
+	logger.Debugf("IndexAlias.Swap() completed: %d old shards -> %d new shards",
 		len(oldShards), len(newShards))
 
-	// Verify each new shard's document count for debugging
-	for i, shard := range newShards {
-		if shard != nil {
-			if docCount, err := shard.DocCount(); err != nil {
-				logger.Warnf("New shard %d: error getting doc count: %v", i, err)
-			} else {
-				logger.Infof("New shard %d: contains %d documents", i, docCount)
-			}
-		} else {
-			logger.Warnf("New shard %d: is nil", i)
-		}
-	}
-
 	// Test the searcher with a simple query to verify functionality
 	testCtx := context.Background()
 	testReq := &SearchRequest{
@@ -546,7 +533,7 @@ func (ds *DistributedSearcher) SwapShards(newShards []bleve.Index) error {
 		logger.Errorf("Post-swap searcher test query failed: %v", err)
 		return fmt.Errorf("searcher test failed after shard swap: %w", err)
 	} else {
-		logger.Info("Post-swap searcher test query succeeded")
+		logger.Debug("Post-swap searcher test query succeeded")
 	}
 
 	return nil

+ 50 - 50
internal/nginx_log/task_recovery.go

@@ -40,7 +40,7 @@ func (tr *TaskRecovery) RecoverUnfinishedTasks(ctx context.Context) error {
 		return nil
 	}
 
-	logger.Info("Starting recovery of unfinished indexing tasks")
+	logger.Debug("Starting recovery of unfinished indexing tasks")
 
 	// Get all logs with their index status
 	allLogs := GetAllLogsWithIndexGrouped(func(log *NginxLogWithIndex) bool {
@@ -54,7 +54,7 @@ func (tr *TaskRecovery) RecoverUnfinishedTasks(ctx context.Context) error {
 	for _, log := range allLogs {
 		if tr.needsRecovery(log) {
 			incompleteTasksCount++
-			
+
 			// Reset to queued status and assign queue position
 			if err := tr.recoverTask(ctx, log.Path, queuePosition); err != nil {
 				logger.Errorf("Failed to recover task for %s: %v", log.Path, err)
@@ -65,9 +65,9 @@ func (tr *TaskRecovery) RecoverUnfinishedTasks(ctx context.Context) error {
 	}
 
 	if incompleteTasksCount > 0 {
-		logger.Infof("Recovered %d incomplete indexing tasks", incompleteTasksCount)
+		logger.Debugf("Recovered %d incomplete indexing tasks", incompleteTasksCount)
 	} else {
-		logger.Info("No incomplete indexing tasks found")
+		logger.Debug("No incomplete indexing tasks found")
 	}
 
 	return nil
@@ -81,12 +81,12 @@ func (tr *TaskRecovery) needsRecovery(log *NginxLogWithIndex) bool {
 		// Task was in progress during last shutdown
 		logger.Debugf("Found incomplete indexing task: %s", log.Path)
 		return true
-		
+
 	case string(indexer.IndexStatusQueued):
 		// Task was queued but may not have started
 		logger.Debugf("Found queued indexing task: %s", log.Path)
 		return true
-		
+
 	case string(indexer.IndexStatusError):
 		// Check if error is recent (within last hour before restart)
 		if log.LastIndexed > 0 {
@@ -97,76 +97,76 @@ func (tr *TaskRecovery) needsRecovery(log *NginxLogWithIndex) bool {
 			}
 		}
 	}
-	
+
 	return false
 }
 
 // recoverTask recovers a single indexing task
 func (tr *TaskRecovery) recoverTask(ctx context.Context, logPath string, queuePosition int) error {
-	logger.Infof("Recovering indexing task for: %s (queue position: %d)", logPath, queuePosition)
-	
+	logger.Debugf("Recovering indexing task for: %s (queue position: %d)", logPath, queuePosition)
+
 	// Set status to queued with queue position
 	if err := tr.setTaskStatus(logPath, string(indexer.IndexStatusQueued), queuePosition); err != nil {
 		return err
 	}
-	
+
 	// Queue the recovery task asynchronously with proper context and WaitGroup
 	tr.wg.Add(1)
 	go tr.executeRecoveredTask(tr.ctx, logPath)
-	
+
 	return nil
 }
 
 // executeRecoveredTask executes a recovered indexing task with proper global state and progress tracking
 func (tr *TaskRecovery) executeRecoveredTask(ctx context.Context, logPath string) {
 	defer tr.wg.Done() // Always decrement WaitGroup
-	
+
 	// Check context before starting
 	select {
 	case <-ctx.Done():
-		logger.Infof("Context cancelled, skipping recovery task for %s", logPath)
+		logger.Debugf("Context cancelled, skipping recovery task for %s", logPath)
 		return
 	default:
 	}
-	
+
 	// Add a small delay to stagger recovery tasks, but check context
 	select {
 	case <-time.After(time.Second * 2):
 	case <-ctx.Done():
-		logger.Infof("Context cancelled during delay, skipping recovery task for %s", logPath)
+		logger.Debugf("Context cancelled during delay, skipping recovery task for %s", logPath)
 		return
 	}
-	
-	logger.Infof("Executing recovered indexing task: %s", logPath)
-	
+
+	logger.Debugf("Executing recovered indexing task: %s", logPath)
+
 	// Get processing manager for global state updates
 	processingManager := event.GetProcessingStatusManager()
-	
+
 	// Increment active tasks counter and set global status if this is the first task
 	isFirstTask := atomic.AddInt32(&tr.activeTasks, 1) == 1
 	if isFirstTask {
 		processingManager.UpdateNginxLogIndexing(true)
-		logger.Info("Set global indexing status to true for recovery tasks")
+		logger.Debug("Set global indexing status to true for recovery tasks")
 	}
-	
+
 	// Ensure we always decrement counter and reset global status when no tasks remain
 	defer func() {
 		remainingTasks := atomic.AddInt32(&tr.activeTasks, -1)
 		if remainingTasks == 0 {
 			processingManager.UpdateNginxLogIndexing(false)
-			logger.Info("Set global indexing status to false - all recovery tasks completed")
+			logger.Debug("Set global indexing status to false - all recovery tasks completed")
 		}
 		if r := recover(); r != nil {
 			logger.Errorf("Panic during recovered task execution: %v", r)
 		}
 	}()
-	
+
 	// Set status to indexing
 	if err := tr.setTaskStatus(logPath, string(indexer.IndexStatusIndexing), 0); err != nil {
 		logger.Errorf("Failed to set indexing status for recovered task %s: %v", logPath, err)
 		return
 	}
-	
+
 	// Create progress tracking configuration for recovery task
 	progressConfig := &indexer.ProgressConfig{
 		NotifyInterval: 1 * time.Second,
@@ -184,7 +184,7 @@ func (tr *TaskRecovery) executeRecoveredTask(ctx context.Context, logPath string
 				},
 			})
 
-			logger.Infof("Recovery progress: %s - %.1f%% (Files: %d/%d, Lines: %d/%d)",
+			logger.Debugf("Recovery progress: %s - %.1f%% (Files: %d/%d, Lines: %d/%d)",
 				progress.LogGroupPath, progress.Percentage, progress.CompletedFiles,
 				progress.TotalFiles, progress.ProcessedLines, progress.EstimatedLines)
 		},
@@ -202,10 +202,10 @@ func (tr *TaskRecovery) executeRecoveredTask(ctx context.Context, logPath string
 				},
 			})
 
-			logger.Infof("Recovery completion: %s - Success: %t, Duration: %s, Lines: %d, Size: %d bytes",
+			logger.Debugf("Recovery completion: %s - Success: %t, Duration: %s, Lines: %d, Size: %d bytes",
 				completion.LogGroupPath, completion.Success, completion.Duration,
 				completion.TotalLines, completion.IndexedSize)
-			
+
 			// Send index ready event if recovery was successful
 			if completion.Success {
 				event.Publish(event.Event{
@@ -221,19 +221,19 @@ func (tr *TaskRecovery) executeRecoveredTask(ctx context.Context, logPath string
 			}
 		},
 	}
-	
+
 	// Check context before starting indexing
 	select {
 	case <-ctx.Done():
-		logger.Infof("Context cancelled before indexing, stopping recovery task for %s", logPath)
+		logger.Debugf("Context cancelled before indexing, stopping recovery task for %s", logPath)
 		return
 	default:
 	}
-	
+
 	// Execute the indexing with progress tracking
 	startTime := time.Now()
 	docsCountMap, minTime, maxTime, err := tr.modernIndexer.IndexLogGroupWithProgress(logPath, progressConfig)
-	
+
 	if err != nil {
 		logger.Errorf("Failed to execute recovered indexing task %s: %v", logPath, err)
 		// Set error status
@@ -242,28 +242,28 @@ func (tr *TaskRecovery) executeRecoveredTask(ctx context.Context, logPath string
 		}
 		return
 	}
-	
+
 	// Calculate total documents indexed
 	var totalDocsIndexed uint64
 	for _, docCount := range docsCountMap {
 		totalDocsIndexed += docCount
 	}
-	
+
 	// Save indexing metadata using the log file manager
 	duration := time.Since(startTime)
 	if err := tr.logFileManager.SaveIndexMetadata(logPath, totalDocsIndexed, startTime, duration, minTime, maxTime); err != nil {
 		logger.Errorf("Failed to save recovered index metadata for %s: %v", logPath, err)
 	}
-	
+
 	// Set status to indexed (completed)
 	if err := tr.setTaskStatus(logPath, string(indexer.IndexStatusIndexed), 0); err != nil {
 		logger.Errorf("Failed to set completed status for recovered task %s: %v", logPath, err)
 	}
-	
+
 	// Update searcher shards
 	UpdateSearcherShards()
-	
-	logger.Infof("Successfully completed recovered indexing task: %s, Documents: %d", logPath, totalDocsIndexed)
+
+	logger.Debugf("Successfully completed recovered indexing task: %s, Documents: %d", logPath, totalDocsIndexed)
 }
 
 // setTaskStatus updates the task status in the database using the enhanced persistence layer
@@ -273,33 +273,33 @@ func (tr *TaskRecovery) setTaskStatus(logPath, status string, queuePosition int)
 	if persistence == nil {
 		return fmt.Errorf("persistence manager not available")
 	}
-	
+
 	// Use enhanced SetIndexStatus method
 	return persistence.SetIndexStatus(logPath, status, queuePosition, "")
 }
 
 // Shutdown gracefully stops all recovery tasks
 func (tr *TaskRecovery) Shutdown() {
-	logger.Info("Shutting down task recovery system...")
-	
+	logger.Debug("Shutting down task recovery system...")
+
 	// Cancel all active tasks
 	tr.cancel()
-	
+
 	// Wait for all tasks to complete with timeout
 	done := make(chan struct{})
 	go func() {
 		tr.wg.Wait()
 		close(done)
 	}()
-	
+
 	select {
 	case <-done:
-		logger.Info("All recovery tasks completed successfully")
+		logger.Debug("All recovery tasks completed successfully")
 	case <-time.After(30 * time.Second):
 		logger.Warn("Timeout waiting for recovery tasks to complete")
 	}
-	
-	logger.Info("Task recovery system shutdown completed")
+
+	logger.Debug("Task recovery system shutdown completed")
 }
 
 // Global task recovery manager
@@ -307,16 +307,16 @@ var globalTaskRecovery *TaskRecovery
 
 // InitTaskRecovery initializes the task recovery system - called during application startup
 func InitTaskRecovery(ctx context.Context) {
-	logger.Info("Initializing task recovery system")
-	
+	logger.Debug("Initializing task recovery system")
+
 	// Wait a bit for services to fully initialize
 	time.Sleep(3 * time.Second)
-	
+
 	globalTaskRecovery = NewTaskRecovery(ctx)
 	if err := globalTaskRecovery.RecoverUnfinishedTasks(ctx); err != nil {
 		logger.Errorf("Failed to recover unfinished tasks: %v", err)
 	}
-	
+
 	// Monitor context for shutdown
 	go func() {
 		<-ctx.Done()
@@ -324,4 +324,4 @@ func InitTaskRecovery(ctx context.Context) {
 			globalTaskRecovery.Shutdown()
 		}
 	}()
-}
+}

+ 2 - 2
internal/sitecheck/checker.go

@@ -93,7 +93,7 @@ func (sc *SiteChecker) CollectSites() {
 	sc.sites = make(map[string]*SiteInfo)
 
 	// Debug: log indexed sites count
-	logger.Infof("Found %d indexed sites", len(site.IndexedSites))
+	logger.Debugf("Found %d indexed sites", len(site.IndexedSites))
 
 	// Collect URLs from indexed sites, but only from enabled sites
 	for siteName, indexedSite := range site.IndexedSites {
@@ -143,7 +143,7 @@ func (sc *SiteChecker) CollectSites() {
 		}
 	}
 
-	logger.Infof("Collected %d enabled sites for checking", len(sc.sites))
+	logger.Debugf("Collected %d enabled sites for checking", len(sc.sites))
 }
 
 // loadAllSiteConfigs loads all site configs from database and caches them

+ 12 - 12
internal/sitecheck/service.go

@@ -43,14 +43,14 @@ func (s *Service) waitForSiteCollection(ctx context.Context) {
 
 	// First, wait for the initial cache scan to complete
 	// This is much more efficient than polling
-	logger.Info("Waiting for initial cache scan to complete before site collection...")
+	logger.Debug("Waiting for initial cache scan to complete before site collection...")
 	cache.WaitForInitialScanComplete()
-	logger.Infof("Initial cache scan completed after %v, now collecting sites", time.Since(startTime))
+	logger.Debugf("Initial cache scan completed after %v, now collecting sites", time.Since(startTime))
 
 	// Now collect sites - the cache scanning should have populated IndexedSites
 	s.checker.CollectSites()
 	siteCount := s.checker.GetSiteCount()
-	logger.Infof("Site collection completed: found %d sites after %v", siteCount, time.Since(startTime))
+	logger.Debugf("Site collection completed: found %d sites after %v", siteCount, time.Since(startTime))
 
 	// If no sites found after cache scan, do a brief fallback check
 	if siteCount == 0 {
@@ -75,13 +75,13 @@ func (s *Service) waitForSiteCollection(ctx context.Context) {
 				siteCount, time.Since(startTime))
 
 			if siteCount > 0 {
-				logger.Warnf("Site collection completed via fallback: found %d sites", siteCount)
+				logger.Debugf("Site collection completed via fallback: found %d sites", siteCount)
 				return
 			}
 
 			// Check if we've exceeded max fallback wait time
 			if time.Since(startTime) >= maxWaitTime {
-				logger.Warnf("Site collection fallback timeout after %v - proceeding with empty site list",
+				logger.Debugf("Site collection fallback timeout after %v - proceeding with empty site list",
 					time.Since(startTime))
 				return
 			}
@@ -132,23 +132,23 @@ func (s *Service) Start() {
 	// Initial collection and check with delay to allow cache scanner to complete
 	go kernel.Run(s.ctx, "sitecheck initial collection goroutine", func(ctx context.Context) {
 		sl := logger.NewSessionLogger(ctx)
-		sl.Info("Started sitecheck initial collection goroutine")
+		sl.Debug("Started sitecheck initial collection goroutine")
 		// Give cache scanner more time to start up before checking
 		time.Sleep(5 * time.Second)
 
 		// Wait for cache scanner to collect sites with progressive backoff
 		s.waitForSiteCollection(s.ctx)
 		s.checker.CheckAllSites(s.ctx)
-		sl.Info("Sitecheck initial collection goroutine completed")
+		sl.Debug("Sitecheck initial collection goroutine completed")
 	})
 
 	// Start periodic checking (every 5 minutes)
 	s.ticker = time.NewTicker(5 * time.Minute)
 	go kernel.Run(s.ctx, "sitecheck periodic check goroutine", func(ctx context.Context) {
 		sl := logger.NewSessionLogger(ctx)
-		sl.Info("Started sitecheck periodicCheck goroutine")
+		sl.Debug("Started sitecheck periodicCheck goroutine")
 		s.periodicCheck()
-		sl.Info("Sitecheck periodicCheck goroutine completed")
+		sl.Debug("Sitecheck periodicCheck goroutine completed")
 	})
 }
 
@@ -164,7 +164,7 @@ func (s *Service) Stop() {
 	sl := logger.NewSessionLogger(s.ctx)
 
 	s.running = false
-	sl.Info("Stopping site checking service")
+	sl.Debug("Stopping site checking service")
 
 	if s.ticker != nil {
 		s.ticker.Stop()
@@ -198,11 +198,11 @@ func (s *Service) periodicCheck() {
 func (s *Service) RefreshSites() {
 	go func() {
 		sl := logger.NewSessionLogger(s.ctx)
-		sl.Info("Started sitecheck manual refresh goroutine")
+		sl.Debug("Started sitecheck manual refresh goroutine")
 		logger.Info("Manually refreshing sites")
 		s.checker.CollectSites()
 		s.checker.CheckAllSites(s.ctx)
-		sl.Info("Sitecheck manual refresh goroutine completed")
+		sl.Debug("Sitecheck manual refresh goroutine completed")
 	}()
 }