Cannot run Rust Azure Function through "func start", but works when called directly
I have attempted to reproduce MS's guide: Quickstart: Create a Go or Rust function in Azure using Visual Studio Code.
Here is the directory structure:
(target and .git folders ignored)
├── .cargo
│ └── config.toml
├── src
│ ├── main.rs
├── .funcignore
├── .gitignore
├── azfunction
├── Cargo.lock
├── Cargo.toml
├── function.json
├── host.json
├── local.settings.json
I have made src/main.rs
as in the guide. It simply sets up a GET endpoint at localhost/api/RustPoc :
use std::collections::HashMap;
use std::env;
use std::net::Ipv4Addr;
use warp::{http::Response, Filter};
#[tokio::main]
async fn main() {
let example1 = warp::get()
.and(warp::path("api"))
.and(warp::path("RustPoc"))
.and(warp::query::<HashMap<String, String>>())
.map(|p: HashMap<String, String>| match p.get("name") {
Some(name) => Response::builder().body(format!("Hello, {}. This HTTP triggered function executed successfully.", name)),
None => Response::builder().body(String::from("This HTTP triggered function executed successfully. Pass a name in the query string for a personalized response.")),
});
let port_key = "FUNCTIONS_CUSTOMHANDLER_PORT";
let port: u16 = match env::var(port_key) {
Ok(val) => val.parse().expect("Custom Handler port is not a number!"),
Err(_) => 3000,
};
warp::serve(example1).run((Ipv4Addr::LOCALHOST, port)).await
}
This is compiled into a binary which is then copied to the project root: cargo build --release --target=x86_64-unknown-linux-musl && cp target/x86_64-unknown-linux-musl/release/azfunction .
Here is the contents of local.settings.json
:
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "custom",
"FUNCTIONS_EXTENSION_VERSION": "~4"
},
"ConnectionStrings": {}
}
Here is the contents of function.json
:
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
Here is the contents of host.json
:
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
},
"customHandler": {
"description": {
"defaultExecutablePath": "azfunction",
"workingDirectory": "",
"arguments": []
},
"enableForwardingHttpRequest": true
}
}
The function works locally, when run directly. I can start the API with ./azfunction
and get a response with:
$ curl "http://localhost:3000/api/RustPoc"
This HTTP triggered function executed successfully. Pass a name in the query string for a personalized response.⏎
It works as expected.
However when I start it with func
, I get no response at the endpoint.
Here is probably the key part: "No job functions found. Try making your job classes and methods public. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.)."
Here is the full log of starting the function with func
:
$ func start --port 3000 --verbose
SkipInProcessHost compilation symbol is not defined.
FUNCTIONS_INPROC_NET8_ENABLED app setting is not enabled in local.settings.json
%%%%%%
%%%%%%
@ %%%%%% @
@@ %%%%%% @@
@@@ %%%%%%%%%%% @@@
@@ %%%%%%%%%% @@
@@ %%%% @@
@@ %%% @@
@@ %% @@
%%
%
Azure Functions Core Tools
Core Tools Version: 4.0.6280 Commit hash: N/A +421f0144b42047aa289ce691dc6db4fc8b6143e6 (64-bit)
Function Runtime Version: 4.834.3.22875
[2024-09-13T11:36:55.889Z] Building host: version spec: ~4, startup suppressed: 'False', configuration suppressed: 'False', startup operation id: '9562bb48-abaf-4155-be22-054c9d4e8ada'
[2024-09-13T11:36:55.898Z] Reading host configuration file '/home/torstein/code/azure-function-rust-poc/host.json'
[2024-09-13T11:36:55.899Z] Host configuration file read:
[2024-09-13T11:36:55.899Z] {
[2024-09-13T11:36:55.899Z] "version": "2.0",
[2024-09-13T11:36:55.899Z] "logging": {
[2024-09-13T11:36:55.899Z] "applicationInsights": {
[2024-09-13T11:36:55.899Z] "samplingSettings": {
[2024-09-13T11:36:55.899Z] "isEnabled": true,
[2024-09-13T11:36:55.899Z] "excludedTypes": "Request"
[2024-09-13T11:36:55.899Z] }
[2024-09-13T11:36:55.899Z] }
[2024-09-13T11:36:55.899Z] },
[2024-09-13T11:36:55.899Z] "extensionBundle": {
[2024-09-13T11:36:55.899Z] "id": "Microsoft.Azure.Functions.ExtensionBundle",
[2024-09-13T11:36:55.899Z] "version": "[4.*, 5.0.0)"
[2024-09-13T11:36:55.899Z] },
[2024-09-13T11:36:55.899Z] "customHandler": {
[2024-09-13T11:36:55.899Z] "description": {
[2024-09-13T11:36:55.899Z] "defaultExecutablePath": "azfunction",
[2024-09-13T11:36:55.899Z] "workingDirectory": "",
[2024-09-13T11:36:55.899Z] "arguments": []
[2024-09-13T11:36:55.899Z] },
[2024-09-13T11:36:55.899Z] "enableForwardingHttpRequest": true
[2024-09-13T11:36:55.899Z] }
[2024-09-13T11:36:55.899Z] }
[2024-09-13T11:36:55.927Z] FUNCTIONS_WORKER_RUNTIME set to custom. Skipping WorkerConfig for language: java
[2024-09-13T11:36:55.927Z] FUNCTIONS_WORKER_RUNTIME set to custom. Skipping WorkerConfig for language: node
[2024-09-13T11:36:55.927Z] FUNCTIONS_WORKER_RUNTIME set to custom. Skipping WorkerConfig for language: powershell
[2024-09-13T11:36:55.928Z] FUNCTIONS_WORKER_RUNTIME set to custom. Skipping WorkerConfig for language: python
[2024-09-13T11:36:55.928Z] Looking for extension bundle Microsoft.Azure.Functions.ExtensionBundle at /home/torstein/.azure-functions-core-tools/Functions/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle
[2024-09-13T11:36:55.929Z] Found a matching extension bundle at /home/torstein/.azure-functions-core-tools/Functions/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/4.17.0
[2024-09-13T11:36:55.938Z] Loading functions metadata
[2024-09-13T11:36:55.939Z] Reading functions metadata (Host)
[2024-09-13T11:36:55.943Z] 0 functions found (Host)
[2024-09-13T11:36:55.949Z] 0 functions loaded
[2024-09-13T11:36:55.950Z] Looking for extension bundle Microsoft.Azure.Functions.ExtensionBundle at /home/torstein/.azure-functions-core-tools/Functions/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle
[2024-09-13T11:36:55.950Z] Found a matching extension bundle at /home/torstein/.azure-functions-core-tools/Functions/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/4.17.0
[2024-09-13T11:36:55.950Z] Fetching information on versions of extension bundle Microsoft.Azure.Functions.ExtensionBundle available on https://functionscdn.azureedge.net/public/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/index.json
[2024-09-13T11:36:56.081Z] Skipping bundle download since it already exists at path /home/torstein/.azure-functions-core-tools/Functions/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/4.17.0
[2024-09-13T11:36:56.082Z] Loading extension bundle from /home/torstein/.azure-functions-core-tools/Functions/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/4.17.0/bin
[2024-09-13T11:36:56.082Z] Script Startup resetting load context with base path: '/home/torstein/.azure-functions-core-tools/Functions/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/4.17.0/bin'.
[2024-09-13T11:36:56.086Z] Reading host configuration file '/home/torstein/code/azure-function-rust-poc/host.json'
[2024-09-13T11:36:56.086Z] Host configuration file read:
[2024-09-13T11:36:56.086Z] {
[2024-09-13T11:36:56.086Z] "version": "2.0",
[2024-09-13T11:36:56.086Z] "logging": {
[2024-09-13T11:36:56.087Z] "applicationInsights": {
[2024-09-13T11:36:56.087Z] "samplingSettings": {
[2024-09-13T11:36:56.087Z] "isEnabled": true,
[2024-09-13T11:36:56.087Z] "excludedTypes": "Request"
[2024-09-13T11:36:56.087Z] }
[2024-09-13T11:36:56.087Z] }
[2024-09-13T11:36:56.087Z] },
[2024-09-13T11:36:56.087Z] "extensionBundle": {
[2024-09-13T11:36:56.087Z] "id": "Microsoft.Azure.Functions.ExtensionBundle",
[2024-09-13T11:36:56.087Z] "version": "[4.*, 5.0.0)"
[2024-09-13T11:36:56.087Z] },
[2024-09-13T11:36:56.087Z] "customHandler": {
[2024-09-13T11:36:56.087Z] "description": {
[2024-09-13T11:36:56.087Z] "defaultExecutablePath": "azfunction",
[2024-09-13T11:36:56.087Z] "workingDirectory": "",
[2024-09-13T11:36:56.087Z] "arguments": []
[2024-09-13T11:36:56.087Z] },
[2024-09-13T11:36:56.087Z] "enableForwardingHttpRequest": true
[2024-09-13T11:36:56.087Z] }
[2024-09-13T11:36:56.087Z] }
[2024-09-13T11:36:56.329Z] Initializing Warmup Extension.
[2024-09-13T11:36:56.360Z] Initializing Host. OperationId: '9562bb48-abaf-4155-be22-054c9d4e8ada'.
[2024-09-13T11:36:56.365Z] Host initialization: ConsecutiveErrors=0, StartupCount=1, OperationId=9562bb48-abaf-4155-be22-054c9d4e8ada
[2024-09-13T11:36:56.414Z] LoggerFilterOptions
[2024-09-13T11:36:56.414Z] {
[2024-09-13T11:36:56.414Z] "MinLevel": "None",
[2024-09-13T11:36:56.414Z] "Rules": [
[2024-09-13T11:36:56.414Z] {
[2024-09-13T11:36:56.414Z] "ProviderName": null,
[2024-09-13T11:36:56.414Z] "CategoryName": null,
[2024-09-13T11:36:56.414Z] "LogLevel": null,
[2024-09-13T11:36:56.414Z] "Filter": "<AddFilter>b__0"
[2024-09-13T11:36:56.414Z] },
[2024-09-13T11:36:56.414Z] {
[2024-09-13T11:36:56.414Z] "ProviderName": "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.SystemLoggerProvider",
[2024-09-13T11:36:56.414Z] "CategoryName": null,
[2024-09-13T11:36:56.414Z] "LogLevel": "None",
[2024-09-13T11:36:56.414Z] "Filter": null
[2024-09-13T11:36:56.414Z] },
[2024-09-13T11:36:56.414Z] {
[2024-09-13T11:36:56.414Z] "ProviderName": "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.SystemLoggerProvider",
[2024-09-13T11:36:56.414Z] "CategoryName": null,
[2024-09-13T11:36:56.414Z] "LogLevel": null,
[2024-09-13T11:36:56.414Z] "Filter": "<AddFilter>b__0"
[2024-09-13T11:36:56.414Z] },
[2024-09-13T11:36:56.414Z] {
[2024-09-13T11:36:56.414Z] "ProviderName": "Azure.Functions.Cli.Diagnostics.ColoredConsoleLoggerProvider",
[2024-09-13T11:36:56.414Z] "CategoryName": null,
[2024-09-13T11:36:56.414Z] "LogLevel": null,
[2024-09-13T11:36:56.414Z] "Filter": "<AddFilter>b__0"
[2024-09-13T11:36:56.414Z] }
[2024-09-13T11:36:56.414Z] ]
[2024-09-13T11:36:56.414Z] }
[2024-09-13T11:36:56.414Z] LoggerFilterOptions
[2024-09-13T11:36:56.414Z] {
[2024-09-13T11:36:56.414Z] "MinLevel": "None",
[2024-09-13T11:36:56.414Z] "Rules": [
[2024-09-13T11:36:56.414Z] {
[2024-09-13T11:36:56.414Z] "ProviderName": null,
[2024-09-13T11:36:56.414Z] "CategoryName": null,
[2024-09-13T11:36:56.414Z] "LogLevel": null,
[2024-09-13T11:36:56.414Z] "Filter": "<AddFilter>b__0"
[2024-09-13T11:36:56.414Z] },
[2024-09-13T11:36:56.414Z] {
[2024-09-13T11:36:56.414Z] "ProviderName": "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.SystemLoggerProvider",
[2024-09-13T11:36:56.414Z] "CategoryName": null,
[2024-09-13T11:36:56.415Z] "LogLevel": "None",
[2024-09-13T11:36:56.415Z] "Filter": null
[2024-09-13T11:36:56.415Z] },
[2024-09-13T11:36:56.415Z] {
[2024-09-13T11:36:56.415Z] "ProviderName": "Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.SystemLoggerProvider",
[2024-09-13T11:36:56.415Z] "CategoryName": null,
[2024-09-13T11:36:56.415Z] "LogLevel": null,
[2024-09-13T11:36:56.415Z] "Filter": "<AddFilter>b__0"
[2024-09-13T11:36:56.415Z] },
[2024-09-13T11:36:56.415Z] {
[2024-09-13T11:36:56.415Z] "ProviderName": "Azure.Functions.Cli.Diagnostics.ColoredConsoleLoggerProvider",
[2024-09-13T11:36:56.415Z] "CategoryName": null,
[2024-09-13T11:36:56.415Z] "LogLevel": null,
[2024-09-13T11:36:56.415Z] "Filter": "<AddFilter>b__0"
[2024-09-13T11:36:56.415Z] }
[2024-09-13T11:36:56.415Z] ]
[2024-09-13T11:36:56.415Z] }
[2024-09-13T11:36:56.415Z] ConcurrencyOptions
[2024-09-13T11:36:56.415Z] {
[2024-09-13T11:36:56.415Z] "DynamicConcurrencyEnabled": false,
[2024-09-13T11:36:56.415Z] "MaximumFunctionConcurrency": 500,
[2024-09-13T11:36:56.415Z] "CPUThreshold": 0.8,
[2024-09-13T11:36:56.415Z] "SnapshotPersistenceEnabled": true
[2024-09-13T11:36:56.415Z] }
[2024-09-13T11:36:56.415Z] FunctionResultAggregatorOptions
[2024-09-13T11:36:56.415Z] {
[2024-09-13T11:36:56.415Z] "BatchSize": 1000,
[2024-09-13T11:36:56.415Z] "FlushTimeout": "00:00:30",
[2024-09-13T11:36:56.415Z] "IsEnabled": true
[2024-09-13T11:36:56.415Z] }
[2024-09-13T11:36:56.415Z] SingletonOptions
[2024-09-13T11:36:56.415Z] {
[2024-09-13T11:36:56.415Z] "LockPeriod": "00:00:15",
[2024-09-13T11:36:56.415Z] "ListenerLockPeriod": "00:00:15",
[2024-09-13T11:36:56.415Z] "LockAcquisitionTimeout": "10675199.02:48:05.4775807",
[2024-09-13T11:36:56.415Z] "LockAcquisitionPollingInterval": "00:00:05",
[2024-09-13T11:36:56.415Z] "ListenerLockRecoveryPollingInterval": "00:01:00"
[2024-09-13T11:36:56.415Z] }
[2024-09-13T11:36:56.415Z] ScaleOptions
[2024-09-13T11:36:56.415Z] {
[2024-09-13T11:36:56.415Z] "ScaleMetricsMaxAge": "00:02:00",
[2024-09-13T11:36:56.415Z] "ScaleMetricsSampleInterval": "00:00:10",
[2024-09-13T11:36:56.415Z] "MetricsPurgeEnabled": true,
[2024-09-13T11:36:56.415Z] "IsTargetScalingEnabled": true,
[2024-09-13T11:36:56.415Z] "IsRuntimeScalingEnabled": false
[2024-09-13T11:36:56.415Z] }
[2024-09-13T11:36:56.416Z] Starting JobHost
[2024-09-13T11:36:56.419Z] Starting Host (HostId=d2s3q34-878109003, InstanceId=f2e65c62-6730-4da7-bcbb-a7e31d248b40, Version=4.834.3.22875, ProcessId=160260, AppDomainId=1, InDebugMode=False, InDiagnosticMode=False, FunctionsExtensionVersion=~4)
[2024-09-13T11:36:56.423Z] FUNCTIONS_WORKER_RUNTIME set to custom. Skipping WorkerConfig for language: java
[2024-09-13T11:36:56.424Z] FUNCTIONS_WORKER_RUNTIME set to custom. Skipping WorkerConfig for language: node
[2024-09-13T11:36:56.424Z] FUNCTIONS_WORKER_RUNTIME set to custom. Skipping WorkerConfig for language: powershell
[2024-09-13T11:36:56.424Z] FUNCTIONS_WORKER_RUNTIME set to custom. Skipping WorkerConfig for language: python
[2024-09-13T11:36:56.427Z] LanguageWorkerOptions
[2024-09-13T11:36:56.427Z] {
[2024-09-13T11:36:56.427Z] "WorkerConfigs": []
[2024-09-13T11:36:56.427Z] }
[2024-09-13T11:36:56.430Z] Loading functions metadata
[2024-09-13T11:36:56.430Z] Reading functions metadata (Host)
[2024-09-13T11:36:56.431Z] 0 functions found (Host)
[2024-09-13T11:36:56.439Z] Reading functions metadata (Custom)
[2024-09-13T11:36:56.447Z] 1 functions found (Custom)
[2024-09-13T11:36:56.452Z] 0 functions loaded
[2024-09-13T11:36:56.458Z] Generating 0 job function(s)
[2024-09-13T11:36:56.470Z] No job functions found. Try making your job classes and methods public. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).
[2024-09-13T11:36:56.476Z] HttpOptions
[2024-09-13T11:36:56.476Z] {
[2024-09-13T11:36:56.476Z] "DynamicThrottlesEnabled": false,
[2024-09-13T11:36:56.476Z] "EnableChunkedRequestBinding": false,
[2024-09-13T11:36:56.477Z] "MaxConcurrentRequests": -1,
[2024-09-13T11:36:56.477Z] "MaxOutstandingRequests": -1,
[2024-09-13T11:36:56.477Z] "RoutePrefix": "api"
[2024-09-13T11:36:56.477Z] }
[2024-09-13T11:36:56.478Z] Initializing function HTTP routes
[2024-09-13T11:36:56.478Z] No HTTP routes mapped
[2024-09-13T11:36:56.478Z]
[2024-09-13T11:36:56.484Z] Host initialized (58ms)
[2024-09-13T11:36:56.486Z] Host started (66ms)
[2024-09-13T11:36:56.486Z] Job host started
[2024-09-13T11:37:00.528Z] Executing HTTP request: {
[2024-09-13T11:37:00.528Z] "requestId": "83610b1e-078a-4c39-8300-b7d91b580537",
[2024-09-13T11:37:00.528Z] "method": "GET",
[2024-09-13T11:37:00.528Z] "userAgent": "curl/8.7.1",
[2024-09-13T11:37:00.528Z] "uri": "/api/RustPoc"
[2024-09-13T11:37:00.528Z] }
[2024-09-13T11:37:00.581Z] Executed HTTP request: {
[2024-09-13T11:37:00.582Z] "requestId": "83610b1e-078a-4c39-8300-b7d91b580537",
[2024-09-13T11:37:00.582Z] "identities": "",
[2024-09-13T11:37:00.582Z] "status": "404",
[2024-09-13T11:37:00.582Z] "duration": "53"
[2024-09-13T11:37:00.582Z] }
Attempting to ping the endpoint yields 404:
$ curl -i "http://localhost:3000/api/RustPoc"
HTTP/1.1 404 Not Found
Content-Length: 0
Date: Fri, 13 Sep 2024 11:39:22 GMT
Server: Kestrel
I have tried to add println!
and file logging to the main function. When called with func start
, the binary is never called. The logging is never triggered. When the binary is executed directly with ./azfunction
then the printing is triggered.
System: Fedora 40 x86_64