

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 故障排除和监控功能
<a name="monetization-functions-troubleshooting"></a>

该页面可帮助您诊断常见的功能错误并监控生产中的功能性能。疑难解答部分按症状组织——从您观察到的内容开始，然后按照原因进行修复。

## 监控
<a name="monetization-functions-troubleshooting-monitoring"></a>

### CloudWatch 指标
<a name="monetization-functions-troubleshooting-cw-metrics"></a>

MediaTailor 向 Amazon 发布函数执行指标 CloudWatch。无需选择加入。

**Hook-level metrics** — 每次生命周期挂钩执行一个数据点：


| 指标 | 说明 | Dimensions | 
| --- | --- | --- | 
| PreSessionInitHook.Invocations | 挂钩执行次数 | ConfigurationName | 
| PreSessionInitHook.Errors | 挂钩错误计数 | ConfigurationName | 
| PreSessionInitHook.Latency | 挂钩执行时间 (ms) | ConfigurationName | 
| PreAdsRequestHook.Invocations | 挂钩执行次数 | ConfigurationName | 
| PreAdsRequestHook.Errors | 挂钩错误计数 | ConfigurationName | 
| PreAdsRequestHook.Latency | 挂钩执行时间 (ms) | ConfigurationName | 

**Function-level metrics** — 每个函数执行一个数据点：


| 指标 | 说明 | Dimensions | 
| --- | --- | --- | 
| Function.Invocations | 函数执行次数 | ConfigurationName, FunctionId, FunctionType, HookType | 
| Function.Errors | 函数错误计数 | ConfigurationName, FunctionId, FunctionType, HookType | 
| Function.Latency | 函数执行时间 (ms) | ConfigurationName, FunctionId, FunctionType, HookType | 

有关设置警报和使用这些指标的更多详细信息，请参阅[监控 AWS Elemental MediaTailor 使用亚马逊 CloudWatch 指标](monitoring-cloudwatch-metrics.md)。

### 日志事件
<a name="monetization-functions-troubleshooting-log-events"></a>

MediaTailor 为函数执行发出日志事件。默认情况下会发出错误事件。已完成事件和摘要事件是可选的。


| 事件类型 | 默认/ Opt-in | 日志组 | 说明 | 
| --- | --- | --- | --- | 
| PRE\_SESSION\_INIT\_HOOK\_SUMMARY | Opt-in | 清单日志 | 挂钩执行摘要 (success/error) | 
| PRE\_SESSION\_INIT\_HOOK\_ERROR | 默认 | 清单日志 | 挂机失败，错误类型和原因 | 
| PRE\_SESSION\_INIT\_FUNCTION\_COMPLETED | Opt-in | 清单日志 | 完成的个人功能有 input/output | 
| PRE\_SESSION\_INIT\_FUNCTION\_ERROR | 默认 | 清单日志 | 个别功能故障 | 
| PRE\_ADS\_REQUEST\_HOOK\_SUMMARY | Opt-in | ADS 互动日志 | 挂钩执行摘要 (success/error) | 
| PRE\_ADS\_REQUEST\_HOOK\_ERROR | 默认 | ADS 互动日志 | 挂机失败，错误类型和原因 | 
| PRE\_ADS\_REQUEST\_FUNCTION\_COMPLETED | Opt-in | ADS 互动日志 | 完成的个人功能有 input/output | 
| PRE\_ADS\_REQUEST\_FUNCTION\_ERROR | 默认 | ADS 互动日志 | 个别功能故障 | 

要启用选择加入日志事件，请参阅[监控 AWS Elemental MediaTailor 使用亚马逊 CloudWatch 指标](monitoring-cloudwatch-metrics.md)。

使用该`eventId`字段将钩子级别和函数级事件关联起来，以实现相同的执行。

以下 Amaz CloudWatch on Logs Insights 查询筛选函数错误事件`eventId`以跟踪单次执行：

```
fields @timestamp, eventType, functionId, errorType, cause
| filter eventId = "5dc6f040-0f72-4e8c-a64e-25eeef62708c"
| sort @timestamp asc
```

## 问题排查
<a name="monetization-functions-troubleshooting-guide"></a>

当函数失败时，会在错误事件中 MediaTailor 记录一个`errorType`字段。使用此字段来标识故障类别：


| 错误类型 | 说明 | 
| --- | --- | 
| SYNTAX\_ERROR | 表达式编译失败或遇到运行时类型错误 | 
| RESOURCE\_LIMIT\_ERROR | 表达式超出了 CPU 时间、内存或堆栈深度限制 | 
| RESTRICTION\_ERROR | 表达式使用了被屏蔽的函数，或者超过了输入有效载荷大小限制 | 
| TIMEOUT\_ERROR | 函数执行超过了其时间限制 | 
| VALIDATION\_ERROR | 输出路径的目标是当前挂钩作用域中不可写的字段 | 
| INTERNAL\_ERROR | 与功能无关的基础架构故障 | 

这些条目按症状组织，并在适用的情况下引用这些错误类型。

### 表达式意外返回空值
<a name="monetization-functions-ts-null"></a>

**症状：**您期望填充的输出值在播放器参数中存在`null`或缺失。

**可能的原因：**


| 原因 | 如何识别 | Fix | 
| --- | --- | --- | 
| 此生命周期挂钩中不存在输入字段。 | 你在PRE\_SESSION\_INITIALIZATION函数adsRequest.url中引用了。ADS 请求数据在会话开始时不可用。 | 将函数移至PRE\_ADS\_REQUEST生命周期挂钩，或使用其他输入字段。请参阅[生命周期钩子](monetization-functions-hooks.md)。 | 
| 会话数据中缺少输入字段。 | 你引用了player\_params.campaign\_id，但是玩家在会话初始化时没有传递该参数。 | 用于$exists()在访问之前进行检查:{%$exists(player\_params.campaign\_id) ? player\_params.campaign\_id : 'default'%}. | 
| 你向玩家参数或 ADS 请求写了一个对象或数组。 | 这些命名空间仅接受字符串、数字和布尔值。对象和数组会被过滤掉。 | 在中存储复杂数据，temp.\*并在后续步骤中提取字符串、数字或布尔值。 | 

### R@@ `ESOURCE_LIMIT_ERROR：堆栈溢出`
<a name="monetization-functions-ts-stack-overflow"></a>

**症状：**函数在出现`errorType: "RESOURCE_LIMIT_ERROR"`和时失败`cause: "Stack overflow error"`。

**原因：**表达式超过了 100 个等级的最大堆栈深度。这种情况通常发生在深度嵌套的条件 (if/then/else) 表达式或复杂的变量赋值中。

这意味着表达式的嵌套层次太多 MediaTailor ，无法处理。

**修复：**简化表达式。将复杂的逻辑分解为多个输出条目或顺序执行器中的多个步骤。

### R@@ `ESOURCE_LIMIT_ERROR`：CPU 超时
<a name="monetization-functions-ts-cpu-timeout"></a>

**症状：**函数在出现`errorType: "RESOURCE_LIMIT_ERROR"`和时失败`cause: "Expression evaluation timeout: Check for infinite loop"`。

**原因：**表达式超过了 100 毫秒的 CPU 时间限制。在大型数据结构上执行昂贵计算的表达式可能会发生这种情况。

**修复：**降低表达式的复杂性。如果您正在处理大型数组，请考虑将该逻辑移至外部服务并使用`HTTP_REQUEST`函数调用它。

### `限制错误：不允许使用`函数
<a name="monetization-functions-ts-function-not-allowed"></a>

**症状：**函数在出现`errorType: "RESTRICTION_ERROR"`和时失败`cause: "Function '<name>' is not allowed"`。

**原因：**该表达式调用的 jsonata 函数不在允许的 38 个函数列表中。常见的示例包括`$filter``$reduce`、`$eval`、`$split`、和`$join`。

**修复：**检查`cause`字段中是否有被屏蔽的函数名称。将其替换为允许的替代方案。有关允许[jsonata 表达式参考](monetization-functions-jsonata.md)的 38 个函数的完整列表，请参阅。

允许使用的常用函数包括`$string``$number`、`$substring`、`$contains`、和`$encodeUrlComponent`。

### RESTR@@ `ICTION_ERROR：表达`式太长
<a name="monetization-functions-ts-expression-too-long"></a>

**症状：**无法使用创建或更新函数`cause: "Expression length <actual> exceeds limit <limit>"`。

**原因：**单个表达式超过 1,000 个字符。

**修复：**将表达式分成较小的部分。使用多个输出条目，或者在顺序执行器中将逻辑分成多个步骤。使用变量绑定 (`:=`) 来避免重复长子表达式。

### HTTP 错误：状态码为空
<a name="monetization-functions-ts-status-null"></a>

**症状：**在`HTTP_REQUEST`函数的输出中，`response.statusCode`是`null`。

**原因：**无法访问外部 API、连接超时或出现网络错误。发生这种情况时， MediaTailor 将设置`response.statusCode`为`null`、设置`response.body`为`null`、设置`response.text`为`"Internal Error"`。

**修复：**`response.statusCode`在访问响应数据之前请务必进行检查：

```
{%response.statusCode = 200 ? response.body.value : 'default'%}
```

此表达式检查 HTTP 调用是否返回了 200 状态码。如果是，则使用响应值。否则，它将回退到默认值。

如果这种情况经常发生，请检查外部 API 是否正常。`RequestTimeoutMilliseconds`如果 API 很慢，可以考虑增加，或者如果你想快速失败，可以考虑减少它。

### HTTP 错误：响应正文为空
<a name="monetization-functions-ts-body-null"></a>

**症状：**`response.statusCode`是 200 但`response.body`确实如此`null`。

**原因：**响应正文要么是无效的 JSON，要么超过 20,000 个字符。 MediaTailor 只能将最多 20,000 个字符的 JSON 响应解析为`response.body`。

**修复：**`response.text`用作后备。该`response.text`字段包含截断为 20,000 个字符的原始响应正文：

```
{%response.statusCode = 200 ? ($exists(response.body.id) ? response.body.id : $substring(response.text, 0, 100)) : 'error'%}
```

如果您需要的数据超过 20,000 个字符的限制，可以考虑要求外部 API 返回较小的响应（例如，通过请求特定字段）。

### HTTP 错误：网址验证失败
<a name="monetization-functions-ts-url-validation"></a>

**症状：**函数在运行时失败，并显示一条关于 URL 格式错误、使用无效方案或超过最大长度的消息。

**可能的原因：**


| 原因 | Fix | 
| --- | --- | 
| 该 URL 不使用http或https。 | 确保 URL 表达式生成一个以http://或开头的 URL https://。 | 
| 表达式评估后，网址超过 2,048 个字符。 | 缩短网址。使用 POST 方法将较大的参数值移到请求正文。 | 
| 网址格式不正确（不是有效的 URI）。 | 检查表达式中是否缺少字符或多余字符。$encodeUrlComponent()用于可能包含特殊字符的查询参数值。 | 

### `VALIDATION_ERROR`
<a name="monetization-functions-ts-validation-error"></a>

**症状：**函数失败`errorType: "VALIDATION_ERROR"`。此错误可能发生在创作时（创建或更新函数时），也可能发生在执行时（函数在会话期间运行时）。

**可能的原因：**


| 原因 | 示例 | Fix | 
| --- | --- | --- | 
| 输出密钥的目标是当前挂钩上不可写入的命名空间。 | adsRequest.url在附加到的函数中写入PRE\_SESSION\_INITIALIZATION。 | 检查生命周期挂钩中允许使用哪些输出命名空间。 PRE\_SESSION\_INITIALIZATION只允许player\_params.\*。要么将函数移到正确的挂钩上，要么更改输出键。请参阅[生命周期钩子](monetization-functions-hooks.md)。 | 
| 输出密钥使用无效字符。 | 一个输出键，比如player\_params.device type（带空格）。只允许使用字母、数字、下划线和连字符。 | 将输出密钥重命名为仅使用有效字符。例如，player\_params.device\_type改用。 | 
| 输出密钥不是以有效的前缀开头。 | 类似于player\_params.myValue或custom.myValue的输出键temp.myValue。 | 使用有效的输出前缀：player\_params.\*temp.\*、或adsRequest.\*。 | 
| JSonata 表达式存在语法错误。 | 缺少结尾引号或条件不完整:{%session.id & %}. | 查看表达式中是否缺少引号、不匹配的圆括号或不支持的运算符（如??或）。?: | 
| HTTP\_REQUEST 函数中缺少必填字段。 | URL 字段为空或未指定方法。 | 确保已设置 URL 和方法字段。方法必须为GET或POST。 | 
| 由表达式构建的 URL 无效。 | 评估后的网址使用了不支持的方案ftp://，例如超过 2,048 个字符或格式错误。 | 验证 URL 表达式是否生成有效的http://或 https:// URL。$encodeUrlComponent()用于可能包含特殊字符的查询参数值。 | 
| HTTP 标头包含无效字符或使用受限名称。 | 标题值包含换行符，或者标题名称为host或transfer-encoding。 | 从标题值中删除无效字符。避免使用受限的标头名称。[HTTP\_REQUEST](monetization-functions-types-http-request.md)有关标题限制，请参阅。 | 

检查错误日志事件中的`cause`字段，它会识别哪个字段或表达式未通过验证。

### `INTERNAL_ERROR`
<a name="monetization-functions-ts-internal-error"></a>

**症状：**函数失败`errorType: "INTERNAL_ERROR"`。

**原因：**发生了与您的功能配置无关的基础设施故障。

**修复：**重试请求。如果错误仍然存在，请联系 Supp AWS ort。