📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

适用版本: 6.8-8.9

1. 错误异常的基本描述 #

unknown day of week 是 Elasticsearch 在解析日期字符串或调度表达式时抛出的异常,表示传入的星期值无法被识别。该异常最常见于以下场景:

  • Watcher 定时调度配置:在 trigger.schedule.weeklycron 表达式中使用了错误的星期值。
  • 日期解析请求:使用 date_histogram 或脚本中对星期字段进行解析时,传入了非法值。
  • Cron 表达式错误:Cron 表达式的星期字段(第 6 位)使用了超出范围或不被支持的值。

当 Elasticsearch 的日期解析器无法将输入映射为有效的星期值时,就会抛出 ElasticsearchParseException: unknown day of week [...]

常见现象 #

  • 创建或修改 Watcher 时报错,Watcher 无法正常启用。
  • 包含星期解析的查询或脚本执行失败,返回 400500 状态码。
  • 集群日志中出现 ElasticsearchParseException,并伴随具体的非法星期值。
  • 使用第三方调度工具(如 Curator、自定义脚本)向 Elasticsearch 发送请求时失败。

典型报错与异常栈 #

ElasticsearchParseException: unknown day of week [8]
ElasticsearchParseException: unknown day of week [mondayy]
Caused by: ElasticsearchParseException: unknown day of week [SOME_DAY]
    at org.elasticsearch.common.joda.JodaDateMathParser.parseWeekday(JodaDateMathParser.java:...)
    at org.elasticsearch.xpack.watcher.trigger.schedule.CronScheduleFactory.parseCronExpression(...)

2. 为什么会发生这个错误 #

unknown day of week 的本质原因是:传入的星期值不在 Elasticsearch 支持的合法范围内,或格式不符合解析器的预期。具体原因包括:

2.1 星期数字超出范围 #

Elasticsearch 中星期数字的标准范围是 1-7,分别对应 Sunday 到 Saturday。使用 08 或更大的数字都会触发该异常。

错误示例:on: [0] 或 on: [8]
正确范围:on: [1, 2, 3, 4, 5, 6, 7]

2.2 星期名称拼写错误 #

Elasticsearch 支持以下英文星期名称(不区分大小写):

数字全称缩写
1sundaysun
2mondaymon
3tuesdaytue
4wednesdaywed
5thursdaythu
6fridayfri
7saturdaysat

拼写错误(如 monedaytueswednesda)均会触发异常。

2.3 Cron 表达式格式错误 #

Cron 表达式中星期字段(第 6 位)的有效值为 SUN-SAT1-7(注意:不同 Cron 实现中 1 可能代表 Sunday 或 Monday,Elasticsearch 使用 Quartz Cron,其中 1=Sunday)。

# 错误示例(数字 8 无效)
0 0 12 ? * 8

# 正确示例
0 0 12 ? * MON-FRI

2.4 本地化星期名称不被支持 #

Elasticsearch 默认使用英文星期名称解析,传入中文(如"星期一")、其他语言或自定义的星期缩写均无法识别。

2.5 Joda-Time 与 Java Time 迁移问题 #

Elasticsearch 在 7.x 开始从 Joda-Time 迁移到 Java Time,部分旧版本文档或脚本中使用的星期格式在新版本中可能不再被支持。

3. 如何排查这个异常 #

建议按以下步骤定位问题:

  1. 定位报错来源:查看完整错误堆栈,确认是 Watcher 调度、Cron 表达式还是查询/脚本触发的异常。
  2. 检查星期值:如果是数字,确认在 1-7 范围内;如果是名称,核对拼写和缩写。
  3. 检查 Cron 表达式:使用在线 Cron 校验工具(如 Cron Maker)验证表达式合法性。
  4. 确认 Elasticsearch 版本:不同版本对星期解析的支持范围略有差异,查阅对应版本文档。
  5. 检查上游数据:如果是脚本或 ingest pipeline 中解析星期字段,检查源数据中是否存在脏数据。

排查时需要注意的问题 #

  • Cron 表达式中星期字段的 1 在 Quartz 中代表 Sunday,而在标准 Unix Cron 中 07 代表 Sunday,两者容易混淆。
  • Watcher 的 weekly 触发器与 cron 触发器对星期值的格式要求不同,不要混用。
  • 如果异常来自 ingest pipeline 中的 date processor,检查 patterns 中是否正确配置了星期格式。

4. 如何解决这个错误 #

方案一:修正 Watcher 调度中的星期值 #

确保 weekly 触发器的 on 字段使用 1-7 的数字或正确的英文名称:

{
  "trigger": {
    "schedule": {
      "weekly": {
        "on": [1, 5],
        "at": "12:00"
      }
    }
  }
}

或使用英文名称:

{
  "trigger": {
    "schedule": {
      "weekly": {
        "on": ["mon", "fri"],
        "at": "12:00"
      }
    }
  }
}

方案二:修正 Cron 表达式中的星期字段 #

使用 Quartz Cron 支持的星期格式:

# 每周一至周五中午 12 点触发
0 0 12 ? * MON-FRI

# 每周日中午 12 点触发
0 0 12 ? * SUN

注意:Quartz Cron 星期字段的有效值为 SUN, MON, TUE, WED, THU, FRI, SAT1-7(1=SUN)。

方案三:修正日期解析中的星期格式 #

如果错误发生在 date_histogram 或脚本中,确保传入的星期值符合 Elasticsearch 的星期格式:

{
  "script": {
    "source": "doc['@timestamp'].value.dayOfWeekEnum.toString()"
  }
}

方案四:处理本地化星期名称 #

如果数据源使用非英文星期名称,需要在 ingest 阶段做映射转换:

{
  "script": {
    "source": """
      def dayMap = [
        '星期一': 'MON', '星期二': 'TUE', '星期三': 'WED',
        '星期四': 'THU', '星期五': 'FRI', '星期六': 'SAT', '星期日': 'SUN'
      ];
      return dayMap.getOrDefault(ctx.day_cn, ctx.day_cn);
    """
  }
}

5. 如何预防此类异常 #

  • 统一星期值规范:在团队内部明确星期值的表示方式(推荐使用英文缩写或 1-7 数字),并在代码规范中注明。
  • 使用 Cron 校验工具:在 CI/CD 流程中加入 Cron 表达式合法性校验,避免非法表达式进入生产环境。
  • 编写 Watcher 前先验证:使用 _validate API 验证 Watcher 配置的正确性,再正式创建。
POST _watcher/watch/_validate
{
  "trigger": { "schedule": { "cron": "0 0 12 ? * MON-FRI" } },
  "condition": { "always": {} }
}
  • 监控 Watcher 执行状态:通过 INFINI Console 监控 Watcher 的执行历史和失败情况,及时发现配置问题。
  • 版本升级前检查:从 7.x 升级到 8.x 时,检查 Watcher 和 Cron 表达式中是否使用了已废弃的星期格式。

借助 INFINI 产品提升排障效率 #

  • INFINI Console 适合查看集群健康度、Watcher 执行状态、错误趋势和请求画像,帮助快速判断异常是配置问题还是系统性问题。
  • INFINI Gateway 适合部署在 Elasticsearch 前面做请求观测、限流和流量治理,尤其适合定位高频错误请求和不合理 DSL。

6. 小结 #

unknown day of week 是一个典型的配置类异常,通常由星期值超出范围、拼写错误或 Cron 表达式格式不正确引起。排查时应优先确认星期值的来源(Watcher 调度、Cron 表达式、查询/脚本),然后对照支持的格式进行修正。通过建立规范的配置校验流程和监控机制,可以有效避免此类问题在生产环境中反复出现。

相关错误 #

附:日志上下文 #

下面保留当前页面中的源码片段,便于结合异常调用栈定位问题:

case "1"; "sun"; "sunday" -> SUNDAY;
case "2"; "mon"; "monday" -> MONDAY;
case "3"; "tue"; "tuesday" -> TUESDAY;
case "4"; "wed"; "wednesday" -> WEDNESDAY;
case "5"; "thu"; "thursday" -> THURSDAY;
case "6"; "fri"; "friday" -> FRIDAY;
case "7"; "sat"; "saturday" -> SATURDAY;
default -> throw new ElasticsearchParseException("unknown day of week [{}]", day);