{"record":{"id":"9eee6ab0d4a1b64d","repo":"flipped-aurora/gin-vue-admin","slug":"error-9eee6a","errorCode":null,"errorMessage":"日志文件不可读取","messagePattern":"日志文件不可读取","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_log_viewer.go","lineNumber":33,"sourceCode":"\t\"time\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\tsystemReq \"github.com/flipped-aurora/gin-vue-admin/server/model/system/request\"\n\tsystemRes \"github.com/flipped-aurora/gin-vue-admin/server/model/system/response\"\n)\n\nconst (\n\tDefaultLogChunkLines = 500\n\tMaxLogChunkBytes     = 2 * 1024 * 1024\n\tlogReadBlockSize     = 64 * 1024\n)\n\nvar (\n\tErrInvalidLogMonth    = errors.New(\"日志月份格式不正确\")\n\tErrInvalidLogDate     = errors.New(\"日志日期格式不正确\")\n\tErrInvalidLogPath     = errors.New(\"日志文件路径不合法\")\n\tErrLogFileNotFound    = errors.New(\"日志文件不存在\")\n\tErrLogFileUnreadable  = errors.New(\"日志文件不可读取\")\n\tErrLogRootUnavailable = errors.New(\"日志目录不可读取\")\n)\n\ntype LogViewerService struct{}\n\nfunc (s *LogViewerService) ListDates(ctx context.Context, month string) (result systemRes.LogDateList, err error) {\n\tresult = systemRes.LogDateList{Month: month, Dates: make([]systemRes.LogDateItem, 0)}\n\tif err = validateLogMonth(month); err != nil {\n\t\treturn result, err\n\t}\n\n\tlogRoot, exists, err := openConfiguredLogRoot()\n\tif err != nil {\n\t\treturn result, err\n\t}\n\tif !exists {\n\t\treturn result, nil\n\t}","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_log_viewer.go#L15-L51","documentation":"ErrLogFileUnreadable is a sentinel error of the log viewer service indicating that a log file exists and passed path validation but could not be opened or read (e.g. permission denied or I/O error). It is returned by failLogViewerRequest, ReadContent, and openValidatedLogFile when os.Open/Read fails for a reason other than the file being missing.","triggerScenarios":"Calling ReadContent for a log file whose path passes validation (correct month/date format, stays inside the log root) but the file cannot be opened: file mode disallows read for the running user, or an I/O error occurs during read. Returned via failLogViewerRequest for the API response.","commonSituations":"Log files written by root or another user while the gin-vue-admin server runs under a lower-privileged account; files with 0600 permissions after log rotation; disk/IO errors; SELinux or container volume mount permission restrictions on the log directory.","solutions":["Check the file permissions of files under the configured log directory (ls -l) and ensure the process user can read them (chmod/chown as needed).","Confirm the server process user actually owns or has group access to the log directory and rotation-created files.","Check container/SELinux context if running in Docker or with enforcing policies.","Inspect server logs for the underlying os error returned alongside the sentinel to identify the exact cause."],"exampleFix":"// before (root-owned rotated log, unreadable by app user)\n// -rw------- 1 root root app-2026-08-31.log\n// after\n// chown appuser:appuser app-2026-08-31.log\n// chmod 0640 app-2026-08-31.log","handlingStrategy":"fallback","validationCode":"const stat = await fs.promises.stat(filePath).catch(() => null)\nif (!stat || !stat.isFile()) throw new Error('log file not found')\nawait fs.promises.access(filePath, fs.constants.R_OK) // throws EACCES early if unreadable","typeGuard":null,"tryCatchPattern":"try {\n  await api.readLogContent({ month, date, fileName })\n} catch (e) {\n  if (e.msg === '日志文件不可读取') {\n    // surface file-permission hint and fall back to server-side log tail via ops\n  } else throw e\n}","preventionTips":["Run the server with a user that owns or has group-read on the log directory.","Configure log rotation to preserve readable modes (e.g. 0640 with a shared group).","Add a startup health check that opens a known log file to catch permission drift early."],"tags":["go","filesystem","log-viewer","file-permissions"],"backgroundTag":"log-file-unreadable","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}