Azure Functions 自定义处理程序(预览版)Azure Functions custom handlers (preview)

每个函数应用由特定于语言的处理程序执行。Every Functions app is executed by a language-specific handler. 尽管 Azure Functions 默认支持许多语言处理程序,但在某些情况下,你可能需要使用其他语言或运行时。While Azure Functions supports many language handlers by default, there are cases where you may want to use other languages or runtimes.

自定义处理程序是可以从 Functions 主机接收事件的轻型 Web 服务器。Custom handlers are lightweight web servers that receive events from the Functions host. 支持 HTTP 基元的任何语言都可以实现自定义处理程序。Any language that supports HTTP primitives can implement a custom handler.

自定义处理程序最适合用于以下场合:Custom handlers are best suited for situations where you want to:

  • 使用当前不受支持的语言(如 Go 和 Rust)实现函数应用。Implement a function app in a language that's not currently supported, such as Go and Rust.
  • 使用当前不受支持的运行时(如 Deno)实现函数应用。Implement a function app in a runtime that's not currently supported, such as Deno.

对于自定义处理程序,可以通过扩展绑定来使用触发器以及输入和输出绑定With custom handlers, you can use triggers and input and output bindings via extension bundles.

概述Overview

下图显示了 Functions 主机与作为自定义处理程序实现的 Web 服务器之间的关系。The following diagram shows the relationship between the Functions host and a web server implemented as a custom handler.

Azure Functions 自定义处理程序概述

  1. 每个事件都会触发发送到 Functions 主机的请求。Each event triggers a request sent to the Functions host. 事件是由 Azure Functions 支持的触发器。An event is any trigger that is supported by Azure Functions.
  2. 然后,Functions 主机向 Web 服务器发出请求有效负载The Functions host then issues a request payload to the web server. 有效负载保存该函数的触发和输入绑定数据以及其他元数据。The payload holds trigger and input binding data and other metadata for the function.
  3. Web 服务器执行单个函数,并向 Functions 主机返回响应有效负载The web server executes the individual function, and returns a response payload to the Functions host.
  4. Functions 主机将数据从响应传递到函数的输出绑定以进行处理。The Functions host passes data from the response to the function's output bindings for processing.

作为自定义处理程序实现的 Azure Functions 应用必须根据几条约定配置 host.json、local.settings.json 和 function.json 文件 。An Azure Functions app implemented as a custom handler must configure the host.json, local.settings.json, and function.json files according to a few conventions.

应用程序结构Application structure

若要实现自定义处理程序,需要准备好应用程序的以下方面的内容:To implement a custom handler, you need the following aspects to your application:

  • 位于应用根目录的 host.json 文件A host.json file at the root of your app
  • 位于应用根目录的 local.settings.json 文件A local.settings.json file at the root of your app
  • 每个函数有一个 function.json 文件(位于与函数名称匹配的文件夹中)A function.json file for each function (inside a folder that matches the function name)
  • 用于运行 Web 服务器的命令、脚本或可执行文件A command, script, or executable, which runs a web server

下图显示了对于名为“MyQueueFunction”的函数和名为“handler.exe”的自定义处理程序可执行文件,这些文件在文件系统上是什么样子。The following diagram shows how these files look on the file system for a function named "MyQueueFunction" and an custom handler executable named handler.exe.

| /MyQueueFunction
|   function.json
|
| host.json
| local.settings.json
| handler.exe

配置Configuration

应用程序是通过 host.json 和 local.settings.json 文件配置的 。The application is configured via the host.json and local.settings.json files.

host.jsonhost.json

host.json 告知 Functions 主机要将请求发送到哪个位置,方法是指向能够处理 HTTP 事件的 Web 服务器。host.json tells the Functions host where to send requests by pointing to a web server capable of processing HTTP events.

自定义处理程序的定义方式是通过 customHandler 节在 host.json 文件中配置有关如何运行 Web 服务器的详细信息。A custom handler is defined by configuring the host.json file with details on how to run the web server via the customHandler section.

{
  "version": "2.0",
  "customHandler": {
    "description": {
      "defaultExecutablePath": "handler.exe"
    }
  }
}

customHandler 节指向 defaultExecutablePath 定义的目标。The customHandler section points to a target as defined by the defaultExecutablePath. 执行目标可以某个命令、可执行文件,或实现 Web 服务器的文件。The execution target may either be a command, executable, or file where the web server is implemented.

使用 arguments 数组将任何参数传递给可执行文件。Use the arguments array to pass any arguments to the executable. 参数支持使用 %% 表示法扩展环境变量(应用程序设置)。Arguments support expansion of environment variables (application settings) using %% notation.

还可以通过 workingDirectory 更改可执行文件使用的工作目录。You can also change the working directory used by the executable with workingDirectory.

{
  "version": "2.0",
  "customHandler": {
    "description": {
      "defaultExecutablePath": "app/handler.exe",
      "arguments": [
        "--database-connection-string",
        "%DATABASE_CONNECTION_STRING%"
      ],
      "workingDirectory": "app"
    }
  }
}
绑定支持Bindings support

可以通过在 host.json 文件中引用扩展捆绑来使用标准触发器以及输入和输出绑定。Standard triggers along with input and output bindings are available by referencing extension bundles in your host.json file.

local.settings.jsonlocal.settings.json

local.settings.json 定义在本地运行函数应用时使用的应用程序设置。local.settings.json defines application settings used when running the function app locally. 由于 local.settings.json 可能包含机密,因此应将其从源代码管理中排除。As it may contain secrets, local.settings.json should be excluded from source control. 在 Azure 中,改用应用程序设置。In Azure, use application settings instead.

对于自定义处理程序,请在“local.settings.json”中将 FUNCTIONS_WORKER_RUNTIME 设置为 CustomFor custom handlers, set FUNCTIONS_WORKER_RUNTIME to Custom in local.settings.json.

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "Custom"
  }
}

备注

在 Linux Premium 上或应用服务计划中,Custom 可能不会被识别为有效的运行时。Custom may not be recognized as a valid runtime on the Linux Premium or App Service plans. 如果这是你的部署目标,则将 FUNCTIONS_WORKER_RUNTIME 设置为空字符串。If that is your deployment target, set FUNCTIONS_WORKER_RUNTIME to an empty string.

函数元数据Function metadata

与自定义处理程序配合使用时,function.json 的内容与在任何其他上下文中定义函数时包含的内容没有什么不同。When used with a custom handler, the function.json contents are no different from how you would define a function under any other context. 唯一的要求是 function.json 文件必须位于名称与函数名称匹配的文件夹中。The only requirement is that function.json files must be in a folder named to match the function name.

以下 function.json 配置了一个具有队列触发器和队列输出绑定的函数。The following function.json configures a function that has a queue trigger and a queue output binding. 因为它位于名为“MyQueueFunction”的文件夹中,所以它定义了一个名为“MyQueueFunction”的函数 。Because it's in a folder named MyQueueFunction, it defines a function named MyQueueFunction.

MyQueueFunction/function.jsonMyQueueFunction/function.json

{
  "bindings": [
    {
      "name": "myQueueItem",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "messages-incoming",
      "connection": "AzureWebJobsStorage"
    },
    {
      "name": "$return",
      "type": "queue",
      "direction": "out",
      "queueName": "messages-outgoing",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

请求有效负载Request payload

接收到队列消息后,Functions 主机会将 HTTP 发布请求发送到自定义处理程序,该处理程序的主体中具有有效负载。When a queue message is received, the Functions host sends an HTTP post request to the custom handler with a payload in the body.

以下代码是一个示例请求有效负载。The following code represents a sample request payload. 该有效负载中的 JSON 结构包含以下两个成员:DataMetadataThe payload includes a JSON structure with two members: Data and Metadata.

Data 成员包含与 function.json 文件中的绑定数组内定义的输入和触发器名称匹配的键。The Data member includes keys that match input and trigger names as defined in the bindings array in the function.json file.

Metadata 成员包含从事件源生成的元数据The Metadata member includes metadata generated from the event source.

{
  "Data": {
    "myQueueItem": "{ message: \"Message sent\" }"
  },
  "Metadata": {
    "DequeueCount": 1,
    "ExpirationTime": "2019-10-16T17:58:31+00:00",
    "Id": "800ae4b3-bdd2-4c08-badd-f08e5a34b865",
    "InsertionTime": "2019-10-09T17:58:31+00:00",
    "NextVisibleTime": "2019-10-09T18:08:32+00:00",
    "PopReceipt": "AgAAAAMAAAAAAAAAAgtnj8x+1QE=",
    "sys": {
      "MethodName": "QueueTrigger",
      "UtcNow": "2019-10-09T17:58:32.2205399Z",
      "RandGuid": "24ad4c06-24ad-4e5b-8294-3da9714877e9"
    }
  }
}

响应有效负载Response payload

根据约定,函数响应采用键/值对格式。By convention, function responses are formatted as key/value pairs. 支持的键包括:Supported keys include:

有效负载键Payload key 数据类型Data type 备注Remarks
Outputs objectobject 保存由 function.json 中的 bindings 数组定义的响应值。Holds response values as defined by the bindings array in function.json.

例如,如果一个函数配置有名为“myQueueOutput”的队列输出绑定,则 Outputs 包含一个名为 myQueueOutput 的键,该键由自定义处理程序设置为发送到队列的消息。For instance, if a function is configured with a queue output binding named "myQueueOutput", then Outputs contains a key named myQueueOutput, which is set by the custom handler to the messages that are sent to the queue.
Logs arrayarray 消息将显示在 Functions 调用日志中。Messages appear in the Functions invocation logs.

在 Azure 中运行时,消息显示在 Application Insights 中。When running in Azure, messages appear in Application Insights.
ReturnValue stringstring 将输出配置为 function.json 文件中的 $return 时用于提供响应。Used to provide a response when an output is configured as $return in the function.json file.

下面是一个响应有效负载的示例。This is an example of a response payload.

{
  "Outputs": {
    "res": {
      "body": "Message enqueued"
    },
    "myQueueOutput": [
      "queue message 1",
      "queue message 2"
    ]
  },
  "Logs": [
    "Log message 1",
    "Log message 2"
  ],
  "ReturnValue": "{\"hello\":\"world\"}"
}

示例Examples

自定义处理程序可以使用支持接收 HTTP 事件的任何语言实现。Custom handlers can be implemented in any language that supports receiving HTTP events. 以下示例演示如何使用 Go 编程语言实现自定义处理程序。The following examples show how to implement a custom handler using the Go programming language.

带绑定的函数Function with bindings

此示例中实现的方案使用一个名为 order 的函数,该函数接受包含某个表示产品订单的有效负载的 POSTThe scenario implemented in this example features a function named order that accepts a POST with a payload representing a product order. 将订单发布到该函数时,会创建队列存储消息并返回 HTTP 响应。As an order is posted to the function, a Queue Storage message is created and an HTTP response is returned.

实现Implementation

在名为 order 的文件夹中,function.json 文件将配置 HTTP 触发的函数。 In a folder named order, the function.json file configures the HTTP-triggered function.

order/function.jsonorder/function.json

{
  "bindings": [
    {
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": ["post"]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "queue",
      "name": "message",
      "direction": "out",
      "queueName": "orders",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

此函数定义为返回 HTTP 响应并输出队列存储消息的 HTTP 触发的函数This function is defined as an HTTP triggered function that returns an HTTP response and outputs a Queue storage message.

在应用的根目录中,host.json 文件配置为运行名为 handler.exe(在 Linux 或 macOS 中为 handler)的可执行文件。At the root of the app, the host.json file is configured to run an executable file named handler.exe (handler in Linux or macOS).

{
  "version": "2.0",
  "customHandler": {
    "description": {
      "defaultExecutablePath": "handler.exe"
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[1.*, 2.0.0)"
  }
}

这是发送到 Functions 运行时的 HTTP 请求。This is the HTTP request sent to the Functions runtime.

POST http://127.0.0.1:7071/api/order HTTP/1.1
Content-Type: application/json

{
  "id": 1005,
  "quantity": 2,
  "color": "black"
}

然后,Functions 运行时将以下 HTTP 请求发送到自定义处理程序:The Functions runtime will then send the following HTTP request to the custom handler:

POST http://127.0.0.1:<FUNCTIONS_CUSTOMHANDLER_PORT>/order HTTP/1.1
Content-Type: application/json

{
  "Data": {
    "req": {
      "Url": "http://localhost:7071/api/order",
      "Method": "POST",
      "Query": "{}",
      "Headers": {
        "Content-Type": [
          "application/json"
        ]
      },
      "Params": {},
      "Body": "{\"id\":1005,\"quantity\":2,\"color\":\"black\"}"
    }
  },
  "Metadata": {
  }
}

备注

为简洁起见,删除了有效负载的某些部分。Some portions of the payload were removed for brevity.

handler.exe 是已编译的 Go 自定义处理程序,它运行 Web 服务器并响应来自 Functions 主机的函数调用请求。handler.exe is the compiled Go custom handler program that runs a web server and responds to function invocation requests from the Functions host.

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "os"
)

type InvokeRequest struct {
    Data     map[string]json.RawMessage
    Metadata map[string]interface{}
}

type InvokeResponse struct {
    Outputs     map[string]interface{}
    Logs        []string
    ReturnValue interface{}
}

func orderHandler(w http.ResponseWriter, r *http.Request) {
    var invokeRequest InvokeRequest

    d := json.NewDecoder(r.Body)
    d.Decode(&invokeRequest)

    var reqData map[string]interface{}
    json.Unmarshal(invokeRequest.Data["req"], &reqData)

    outputs := make(map[string]interface{})
    outputs["message"] = reqData["Body"]

    resData := make(map[string]interface{})
    resData["body"] = "Order enqueued"
    outputs["res"] = resData
    invokeResponse := InvokeResponse{outputs, nil, nil}

    responseJson, _ := json.Marshal(invokeResponse)

    w.Header().Set("Content-Type", "application/json")
    w.Write(responseJson)
}

func main() {
    customHandlerPort, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT")
    if !exists {
        customHandlerPort = "8080"
    }
    mux := http.NewServeMux()
    mux.HandleFunc("/order", orderHandler)
    fmt.Println("Go server Listening on: ", customHandlerPort)
    log.Fatal(http.ListenAndServe(":"+customHandlerPort, mux))
}

在此示例中,自定义处理程序运行一个 Web 服务器来处理 HTTP 事件,并设置为通过 FUNCTIONS_CUSTOMHANDLER_PORT 侦听请求。In this example, the custom handler runs a web server to handle HTTP events and is set to listen for requests via the FUNCTIONS_CUSTOMHANDLER_PORT.

尽管 Functions 主机在 /api/order 处收到原始 HTTP 请求,它也会使用函数名称(其文件夹名称)来调用自定义处理程序。Even though the Functions host received original HTTP request at /api/order, it invokes the custom handler using the function name (its folder name). 在此示例中,该函数在 /order 路径中定义。In this example, the function is defined at the path of /order. 主机在 /order 路径中向自定义处理程序发送 HTTP 请求。The host sends the custom handler an HTTP request at the path of /order.

POST 请求发送到此函数时,可通过 HTTP 请求正文获取触发器数据和函数元数据。As POST requests are sent to this function, the trigger data and function metadata are available via the HTTP request body. 可以在有效负载的 Data.req.Body 中访问原始 HTTP 请求正文。The original HTTP request body can be accessed in the payload's Data.req.Body.

函数的响应采用键/值对格式,其中,Outputs 成员保存一个 JSON 值,该值中的键与 function.json 文件中定义的输出相匹配。The function's response is formatted into key/value pairs where the Outputs member holds a JSON value where the keys match the outputs as defined in the function.json file.

下面是此处理程序返回到 Functions 主机的示例有效负载。This is an example payload that this handler returns to the Functions host.

{
  "Outputs": {
    "message": "{\"id\":1005,\"quantity\":2,\"color\":\"black\"}",
    "res": {
      "body": "Order enqueued"
    }
  },
  "Logs": null,
  "ReturnValue": null
}

通过将 message 输出设置为等于来自请求的订单数据,该函数将该订单数据输出到已配置的队列。By setting the message output equal to the order data that came in from the request, the function outputs that order data to the configured queue. Functions 主机还会将在 res 中配置的 HTTP 响应返回给调用方。The Functions host also returns the HTTP response configured in res to the caller.

仅限 HTTP 的函数HTTP-only function

对于没有其他绑定或输出的 HTTP 触发的函数,你可能希望处理程序直接处理 HTTP 请求和响应,而不是处理自定义处理程序请求响应有效负载。For HTTP-triggered functions with no additional bindings or outputs, you may want your handler to work directly with the HTTP request and response instead of the custom handler request and response payloads. 可以使用 enableForwardingHttpRequest 设置在 host.json 中配置此行为。This behavior can be configured in host.json using the enableForwardingHttpRequest setting.

重要

自定义处理程序功能的主要用途是在 Azure Functions 上启用当前不具有一流支持的语言和运行时。The primary purpose of the custom handlers feature is to enable languages and runtimes that do not currently have first-class support on Azure Functions. 虽然可以使用自定义处理程序运行 Web 应用程序,但 Azure Functions 不是标准的反向代理。While it may be possible to run web applications using custom handlers, Azure Functions is not a standard reverse proxy. 某些功能(如响应流式处理、HTTP/2 和 Websocket)不可用。Some features such as response streaming, HTTP/2, and WebSockets are not available. HTTP 请求的某些组件(如某些标头和路由)可能会受到限制。Some components of the HTTP request such as certain headers and routes may be restricted. 应用程序也可能遇到过多的冷启动Your application may also experience excessive cold start.

若要解决这些情况,请考虑在 Azure 应用服务上运行 Web 应用。To address these circumstances, consider running your web apps on Azure App Service.

以下示例演示如何配置一个没有其他绑定或输出的 HTTP 触发函数。The following example demonstrates how to configure an HTTP-triggered function with no additional bindings or outputs. 此示例中实现的方案使用了一个名为 hello 的、接受 GETPOST 的函数。The scenario implemented in this example features a function named hello that accepts a GET or POST .

实现Implementation

在名为“hello”的文件夹中,function.json 文件会配置 HTTP 触发的函数 。In a folder named hello, the function.json file configures the HTTP-triggered function.

hello/function.jsonhello/function.json

{
  "bindings": [
    {
      "type": "httpTrigger",
      "authLevel": "anonymous",
      "direction": "in",
      "name": "req",
      "methods": ["get", "post"]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

该函数配置为接受 GETPOST 请求,结果值通过名为 res 的参数提供。The function is configured to accept both GET and POST requests and the result value is provided via an argument named res.

在应用的根目录中,host.json 文件配置为运行 handler.exeenableForwardingHttpRequest 设置为 trueAt the root of the app, the host.json file is configured to run handler.exe and enableForwardingHttpRequest is set to true.

{
  "version": "2.0",
  "customHandler": {
    "description": {
      "defaultExecutablePath": "handler.exe"
    },
    "enableForwardingHttpRequest": true
  }
}

如果 enableForwardingHttpRequesttrue,仅限 HTTP 的函数的行为与默认的自定义处理程序行为之间存在以下区别:When enableForwardingHttpRequest is true, the behavior of HTTP-only functions differs from the default custom handlers behavior in these ways:

  • HTTP 请求不包含自定义处理程序请求有效负载。The HTTP request does not contain the custom handlers request payload. Functions 主机使用原始 HTTP 请求的副本调用处理程序。Instead, the Functions host invokes the handler with a copy of the original HTTP request.
  • Functions 主机通过与原始请求相同的路径调用处理程序,包括任何查询字符串参数。The Functions host invokes the handler with the same path as the original request including any query string parameters.
  • Functions 主机返回处理程序的 HTTP 响应副本作为对原始请求的响应。The Functions host returns a copy of the handler's HTTP response as the response to the original request.

下面是对 Functions 主机的 POST 请求。The following is a POST request to the Functions host. 然后,Functions 主机将请求的副本发送到相同路径中的自定义处理程序。The Functions host then sends a copy of the request to the custom handler at the same path.

POST http://127.0.0.1:7071/api/hello HTTP/1.1
Content-Type: application/json

{
  "message": "Hello World!"
}

文件 handler.go 实现 Web 服务器和 HTTP 函数。The file handler.go file implements a web server and HTTP function.

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "os"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    if r.Method == "GET" {
        w.Write([]byte("hello world"))
    } else {
        body, _ := ioutil.ReadAll(r.Body)
        w.Write(body)
    }
}

func main() {
    customHandlerPort, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT")
    if !exists {
        customHandlerPort = "8080"
    }
    mux := http.NewServeMux()
    mux.HandleFunc("/api/hello", helloHandler)
    fmt.Println("Go server Listening on: ", customHandlerPort)
    log.Fatal(http.ListenAndServe(":"+customHandlerPort, mux))
}

在此示例中,自定义处理程序创建一个 Web 服务器来处理 HTTP 事件,并设置为通过 FUNCTIONS_CUSTOMHANDLER_PORT 侦听请求。In this example, the custom handler creates a web server to handle HTTP events and is set to listen for requests via the FUNCTIONS_CUSTOMHANDLER_PORT.

通过返回一个字符串来处理 GET 请求,POST 请求具有对请求正文的访问权限。GET requests are handled by returning a string, and POST requests have access to the request body.

此处订单函数的路由为 /api/hello,与原始请求相同。The route for the order function here is /api/hello, same as the original request.

备注

FUNCTIONS_CUSTOMHANDLER_PORT 不是用于调用函数的面向公众的端口。The FUNCTIONS_CUSTOMHANDLER_PORT is not the public facing port used to call the function. 此端口由 Functions 主机用来调用自定义处理程序。This port is used by the Functions host to call the custom handler.

正在部署Deploying

可将自定义处理程序部署到每个 Azure Functions 托管选项。A custom handler can be deployed to every Azure Functions hosting option. 如果处理程序需要操作系统或平台依赖项(如语言运行时),则可能需要使用自定义容器。If your handler requires operating system or platform dependencies (such as a language runtime), you may need to use a custom container.

在 Azure 中为自定义处理程序创建函数应用时,建议选择 .NET Core 作为堆栈。When creating a function app in Azure for custom handlers, we recommend you select .NET Core as the stack. 未来将为自定义处理程序添加“自定义”堆栈。A "Custom" stack for custom handlers will be added in the future.

若要使用 Azure Functions Core Tools 部署自定义处理程序应用,请运行以下命令。To deploy a custom handler app using Azure Functions Core Tools, run the following command.

func azure functionapp publish $functionAppName

备注

请确保运行自定义处理程序所需的所有文件都位于文件夹中,并包含在部署中。Ensure all files required to run your custom handler are in the folder and included in the deployment. 如果自定义处理程序是二进制可执行文件或具有特定于平台的依赖项,请确保这些文件与目标部署平台相匹配。If your custom handler is a binary executable or has platform-specific dependencies, ensure these files match the target deployment platform.

限制Restrictions

  • 自定义处理程序 Web 服务器需要在 60 秒内启动。The custom handler web server needs to start within 60 seconds.

示例Samples

有关如何在各种不同的语言中实现函数的示例,请参阅自定义处理程序示例 GitHub 存储库Refer to the custom handler samples GitHub repo for examples of how to implement functions in a variety of different languages.

故障排除和支持Troubleshooting and support

跟踪日志记录Trace logging

如果自定义处理程序进程无法启动,或在与 Functions 主机通信时出现问题,可将函数应用的日志级别提高到 Trace 以查看来自主机的更多诊断消息。If your custom handler process fails to start up or if it has problems communicating with the Functions host, you can increase the function app's log level to Trace to see more diagnostic messages from the host.

若要更改函数应用的默认日志级别,请在 host.json 的 logging 部分中配置 logLevel 设置。To change the function app's default log level, configure the logLevel setting in the logging section of host.json.

{
  "version": "2.0",
  "customHandler": {
    "description": {
      "defaultExecutablePath": "handler.exe"
    }
  },
  "logging": {
    "logLevel": {
      "default": "Trace"
    }
  }
}

Functions 主机输出额外的日志消息,包括与自定义处理程序进程相关的信息。The Functions host outputs extra log messages including information related to the custom handler process. 使用日志调查启动自定义处理程序进程或调用自定义处理程序中的函数时所遇到的问题。Use the logs to investigate problems starting your custom handler process or invoking functions in your custom handler.

日志在本地被输出到控制台。Locally, logs are printed to the console.

在 Azure 中,查询 Application Insights 跟踪以查看日志消息。In Azure, query Application Insights traces to view the log messages. 如果应用生成大量日志,则只有一个日志消息子集会被发送到 Application Insights。If your app produces a high volume of logs, only a subset of log messages are sent to Application Insights. 禁用采样以确保记录所有消息。Disable sampling to ensure all messages are logged.

以隔离方式测试自定义处理程序Test custom handler in isolation

自定义处理程序应用是一个 Web 服务器进程,因此,通过使用 cURLPostman 等工具发送模拟 HTTP 请求来自行启动该应用程序并测试函数调用可能会有所帮助。Custom handler apps are a web server process, so it may be helpful to start it on its own and test function invocations by sending mock HTTP requests using a tool like cURL or Postman.

还可以在 CI/CD 管道中使用此策略以在自定义处理程序上运行自动化测试。You can also use this strategy in your CI/CD pipelines to run automated tests on your custom handler.

执行环境Execution environment

自定义处理程序与典型 Azure Functions 应用在同一环境中运行。Custom handlers run in the same environment as a typical Azure Functions app. 测试处理程序,以确保环境包含其运行所需的所有依赖项。Test your handler to ensure the environment contains all the dependencies it needs to run. 对于需要其他依赖项的应用,你可能需要使用 Azure Functions 高级计划上托管的自定义容器映像来运行它们。For apps that require additional dependencies, you may need to run them using a custom container image hosted on Azure Functions Premium plan.

获取支持Get support

如果你需要有关包含自定义处理程序的函数应用的帮助,可通过常规支持渠道提交请求。If you need help on a function app with custom handlers, you can submit a request through regular support channels. 但是,由于用于生成自定义处理程序应用的语言多种多样,因此支持并不是无限的。However, due to the wide variety of possible languages used to build custom handlers apps, support is not unlimited.

如果 Functions 主机在启动自定义处理程序进程或与自定义处理程序进程通信时遇到问题,可以获取相关支持。Support is available if the Functions host has problems starting or communicating with the custom handler process. 对于针对自定义处理程序进程的内部工作原理的问题(例如所选语言或框架的问题),我们的支持团队无法在此上下文中提供帮助。For problems specific to the inner workings of your custom handler process, such as issues with the chosen language or framework, our Support Team is unable to provide assistance in this context.