目录设计原则:命名规范与分片策略

日志目录怎么设计?很多人上来就建个 logs/ 文件夹,把所有文件往里一扔。嗯,这种做法,我见过太多团队踩坑了。今天咱们聊聊目录设计的几个核心原则。

命名规范:小写字母 + 下划线

先说命名。我个人习惯,日志目录和文件名一律用小写字母加下划线。为什么?

  • 大小写敏感问题:Linux 系统里 AppLog 和 applog 是两个目录。你写脚本的时候,一不小心就搞混了。我在项目中遇到过,因为大小写不一致,日志采集 agent 漏掉了整整一周的数据。
  • 跨平台兼容:Windows 不区分大小写,但 Linux 区分。你想想看,开发机上是 Windows,生产环境是 Linux,命名不一致,排查问题的时候多痛苦。
  • 下划线 vs 连字符:连字符 - 在某些脚本解析时可能被当成减号。下划线就安全得多。而且,下划线在视觉上更像一个「分隔符」,一眼就能看出层级关系。

推荐命名格式:{服务名}_{模块名}_{日期}_{序号}.log

示例:user_service_login_2025_01_15_001.log

小技巧:文件名里不要用空格。空格在命令行里需要转义,写脚本的时候特别烦人。用下划线代替,清爽多了。

按时间分片:年/月/日

日志文件不能无限增长。一个文件写几个月,打开都费劲。所以,按时间分片是必须的。

我建议的层级结构:年/月/日/

logs/
├── 2025/
│   ├── 01/
│   │   ├── 01/
│   │   │   ├── user_service_login_2025_01_01_001.log
│   │   │   └── user_service_login_2025_01_01_002.log
│   │   ├── 02/
│   │   └── ...
│   ├── 02/
│   └── ...
└── 2026/
    └── ...

为什么这么分?

  • 查询效率高:你想查某一天的日志,直接进对应日期的目录就行。不用遍历整个文件系统。
  • 归档方便:过期的日志,直接打包整个月份或年份的目录。我曾经帮一个客户做日志归档,他们之前所有日志都在一个目录里,归档脚本跑了三天才跑完。
  • 清理策略清晰:保留最近 30 天的日志?直接删掉 30 天前的目录。简单粗暴,不会误删。

注意:不要用 YYYY-MM-DD 作为目录名。连字符在路径里虽然合法,但某些工具(比如 Hadoop 的 HDFS)对连字符的处理有坑。用 / 分隔的纯数字目录,最安全。

按服务/模块分片

一个大型系统,可能有几十个微服务。所有日志混在一起,你根本没法查。所以,按服务或模块分片是第二层维度。

我常用的结构:logs/{服务名}/{环境}/{年}/{月}/{日}/

logs/
├── user-service/
│   ├── prod/
│   │   ├── 2025/
│   │   │   ├── 01/
│   │   │   │   ├── 01/
│   │   │   │   │   ├── login_2025_01_01_001.log
│   │   │   │   │   └── register_2025_01_01_001.log
│   │   │   │   └── 02/
│   │   │   └── 02/
│   │   └── ...
│   └── dev/
└── order-service/
    └── ...

这样做的好处:

  • 隔离性:每个服务只管自己的目录。日志采集 agent 可以针对不同服务配置不同的采集策略。
  • 权限控制:不同团队只对自己负责的服务目录有读写权限。我曾经见过,因为权限没隔离,一个开发误删了另一个服务的日志,导致线上问题排查了整整两天。
  • 扩展性:新服务上线,直接新建一个目录就行。不影响现有结构。

避免单目录文件过多

一个目录里放几万个文件?文件系统会崩溃的。Linux 的 ext4 文件系统,单个目录下文件数超过 10 万,性能就会急剧下降。ls 命令都要卡半天。

怎么避免?

  1. 时间分片要细:按天分片是最低要求。如果日志量特别大,可以按小时分片。
  2. 文件大小限制:单个日志文件不要超过 100MB。超过就滚动,生成新文件。
  3. 子目录打散:如果一天内的日志文件还是太多,可以在日期目录下再加一层哈希子目录。

经验值参考:

日志量级 推荐分片粒度 单目录文件数上限
日均 < 1GB 按天 1000
日均 1GB ~ 100GB 按小时 5000
日均 > 100GB 按小时 + 哈希子目录 10000

我曾经帮一个日处理 500GB 日志的系统做优化。他们之前所有日志都在一个目录里,文件数超过 200 万。优化后,按小时 + 服务分片,每个目录最多 2000 个文件。查询速度提升了 10 倍以上。

整体结构图

下面这张图,把上面说的几个原则串起来了。你可以把它当成一个模板,直接套用。

日志目录设计核心原则 logs/ user-service/ order-service/ payment-service/ prod/ dev/ prod/ prod/ 2025/ 2025/ 2025/ 2025/ 01/ 02/ 01/ 01/ 01/ 01/ 02/ 命名规范 小写字母 + 下划线 避免单目录 文件过多

这张图展示了从根目录到具体日志文件的完整路径。你想想看,按照这个结构,要查 user-service 在 2025 年 1 月 1 日的生产环境日志,路径就是 logs/user-service/prod/2025/01/01/。是不是一目了然?

避坑指南

最后,分享几个我踩过的坑:

  • 不要用中文命名:虽然现代文件系统支持 UTF-8,但很多日志采集工具对中文支持不好。我曾经因为文件名里带了个中文「日志」两个字,导致 ELK 采集端直接报错。
  • 不要用特殊字符:比如 @、#、$、% 这些。在 shell 脚本里,它们有特殊含义,容易引发意想不到的问题。
  • 目录层级不要太深:超过 5 层,路径就会变得很长。Windows 系统有 260 个字符的路径长度限制。虽然 Linux 没有这个限制,但太深的目录结构,操作起来也不方便。
  • 统一规范,强制执行:规范定好了,就要通过脚本或工具强制执行。不要指望开发人员自觉遵守。我在项目中,都是通过日志框架的配置模板,自动生成符合规范的目录结构。

重要提醒:目录设计一旦确定,后期改造成本极高。因为所有日志采集、归档、清理脚本都依赖这个结构。所以,一开始就要想清楚,宁可多花点时间设计,也不要后期返工。