All Products
Search
Document Center

Use fun local to debug locally

Last Updated: Mar 27, 2020

fun install is a subcommand of Fun. fun local allows you to run functions within a simulated local Function Compute environment and provides a step-by-step debugging feature. This command improves the application development experience of Function Compute and provides a new troubleshooting method. fun local provides the fun local invoke and fun local start subcommands.

fun local invoke allows you to run event functions locally, and fun local start allows you to run HTTP trigger functions and event functions locally. When you use the fun local start command, HTTP trigger functions can be triggered by browsers to run, and event functions can be called by InvokeFunction API operations or SDKs.

Note:fun local has been integrated into graphic plug-ins of integrated development environments such as Visual Studio Code, IntelliJ IDEA, and PyCharm. Compared with command lines, these plug-ins provide enhanced graphical operations. Therefore,

fun local invoke

Syntax

You can use fun local invoke -h to view the help information of the fun local invoke command:

  1. $ fun local invoke -h
  2. Usage: invoke [options] <[service/]function>
  3. Run your serverless application locally for quick development & testing.
  4. Options:
  5. -d, --debug-port <port> used for local debugging
  6. -c, --config <ide> print out ide debug configuration. Options are VSCode
  7. -e, --event <path> event file containing event data passed to the function
  8. -h, --help output usage information

Run functions locally

The syntax to run a function is as follows:

  1. fun local invoke [options] <[service/]function>

where the options and the service parameter are optional.fun local invoke allows you to call a function by using the following syntax to specify the service and function names:

  1. fun local invoke function
  2. fun local invoke service/function

If you want to specify a function more precisely, you can specify it in the service/function format.

Note: If template.yml contains multiple services, and multiple services contain functions with the same name, only the first function that matches will be run when you specify a function name.

Run Java functions locally

Java is a compiled language. Functions written in Java must be run after compilation. You can use the fun build [function] command to compile a function. For example, to compile a function named java8, use the following command:

  1. fun build java8

After the command is run, fun displays the following log information:

  1. using template: template.yml
  2. start building function dependencies without docker
  3. building localdemo/java8
  4. running task flow MavenTaskFlow
  5. running task: MavenCompileTask
  6. running task: MavenCopyDependencies
  7. running task: CopyMavenArtifacts
  8. Build Success
  9. Built artifacts: .fun/build/artifacts
  10. Built template: .fun/build/artifacts/template.yml
  11. Tips for next step
  12. ======================
  13. * Invoke Event Function: fun local invoke
  14. * Invoke Http Function: fun local start
  15. * Deploy Resources: fun deploy

You can use the fun local invoke command to run the function after compilation.

Debug locally

fun local invoke provides the -d and —debug-port options to step through the code locally. fun local provides debugging methods that are based on the debugging protocol used by all programming languages. You can use the remote debugging method provided by the programming language you are using.

Debug Node.js and Python functions locally

Functions that run in the Node.js 6, Node.js 8, Python 2.7, Python 3, and Java 8 runtimes are debugged in a similar way. The following debug procedure takes the function named nodejs8 as an example.

You can use fun local invoke nodejs8 to run the nodejs8 function. To debug while the function is running, you can add the -d option and configure the corresponding port.

For example, you can use the following command to specify the debug port to 3000 and debug the function:

  1. fun local invoke -d 3000 nodejs8

We recommend that you add the —config option to display the integrated development environment configurations used for debugging.

  1. fun local invoke -d 3000 --config VSCode nodejs8

The result is as follows:

  1. skip pulling images ...
  2. you can paste these config to .vscode/launch.json, and then attach to your running function
  3. ///////////////// config begin /////////////////
  4. {
  5. "version": "0.2.0",
  6. "configurations": [
  7. {
  8. "name": "fc/localdemo/nodejs8",
  9. "type": "node",
  10. "request": "attach",
  11. "address": "localhost",
  12. "port": 3000,
  13. "localRoot": "/Users/tan/code/fun/examples/local/nodejs8",
  14. "remoteRoot": "/code",
  15. "protocol": "inspect",
  16. "stopOnEntry": false
  17. }
  18. ]
  19. }
  20. ///////////////// config end /////////////////
  21. Debugger listening on ws://0.0.0.0:3000/b65c288b-bd6a-4791-849b-b03e0d16b0ce
  22. For help see https://nodejs.org/en/docs/inspector

The function execution is blocked and will continue to be executed only after you have configured the integrated development environment. The following sections describe how to configure and debug in Visual Studio Code.

The Visual Studio Code configuration is only required when you debug for the first time. You do not need to configure again if you have already configured Visual Studio Code.

Configure in Visual Studio Code

  1. Create a launch.json file in Visual Studio Code.

    1

  2. Copy the configurations displayed between the config begin and config end comments in the preceding log to launch.json.

    2

  3. You can find the function in the DEBUG view.

    3

Visual Studio Code configuration is completed. For more information about how to configure in Visual Studio Code, visit Debugging.

Debug in Visual Studio Code

After the configuration is completed, you can click the editor margin to create breakpoints and click the start debugging icon.

4

The following example shows how to step through the nodejs8 function locally.

5

Debug Java functions locally

Java functions are debugged in the same manner as Node.js and Python functions. The following sections describe how to debug in the commonly used integrated development environments IntelliJ IDEA and Eclipse.

Debug Java functions in Visual Studio Code

The Language Support for Java(TM) by Red Hat and Debugger for Java plug-ins must be installed before you debug Java functions. For more information about how to download plug-ins in the Visual Studio Code marketplace, visit Java in Visual Studio Code.

The following example shows how to debug a Java function in Visual Studio Code.

6

Debug Java functions in IntelliJ IDEA

Configure in IntelliJ IDEA

In the top menu bar, choose Run > Edit Configurations… and perform the following operations:7

  1. Click the Create icon and select Remote to create a remote debug configuration.

    11

  2. Enter a name and specify the port as 3000.

    22

  3. The following example shows the procedure of configuring for remote debugging in IntelliJ IDEA:

    44

Debug in IntelliJ IDEA

Use the following command to run and debug a Java function:

  1. fun local invoke -d 3000 java8

ee

The function is blocked. You must configure in IntelliJ IDEA to continue the following debug procedure. Choose Run > Debug… in the top menu bar or click the debug icon in the tool bar to start debugging.

The following example shows how to perform the remote debug operation in IntelliJ IDEA:

ff

Debug PHP functions locally

The process of debugging PHP functions is different from that of other types of functions.

PHP functions are run using the fun local invoke php72 command and debugged using the -d option, in the same manner as other functions.

  1. fun local invoke -d 3000 --config VSCode php72

However, when you run and debug a PHP function, the function is not blocked and does not wait for the Visual Studio Code debugger to connect, which will cause the function to stop running.

  1. skip pulling images ...
  2. you can paste these config to .vscode/launch.json, and then attach to your running function
  3. ///////////////// config begin /////////////////
  4. {
  5. "version": "0.2.0",
  6. "configurations": [
  7. {
  8. "name": "fc/localdemo/php72",
  9. "type": "php",
  10. "request": "launch",
  11. "port": 3000,
  12. "stopOnEntry": false,
  13. "pathMappings": {
  14. "/code": "/Users/tan/code/fun/examples/local/php7.2"
  15. },
  16. "ignore": [
  17. "/var/fc/runtime/**"
  18. ]
  19. }
  20. ]
  21. }
  22. ///////////////// config end /////////////////
  23. FunctionCompute php7.2 runtime inited.
  24. FC Invoke Start RequestId: 6e8f7ed7-653d-4a6a-94cc-1ef0d028e4b4
  25. FC Invoke End RequestId: 6e8f7ed7-653d-4a6a-94cc-1ef0d028e4b4
  26. hello world
  27. RequestId: 6e8f7ed7-653d-4a6a-94cc-1ef0d028e4b4 Billed Duration: 48 ms Memory Size: 1998 MB Max Memory Used: 58 MB

This is because you must start the Visual Studio Code debugger first for PHP functions.

The procedure to start the debugger for PHP functions is the same as for other functions: You must copy the configurations from the log to launch.json and click the start debugging icon.

You can then run the PHP function in the debug mode in the Visual Studio Code terminal.

  1. fun local invoke -d 3000 php72

rr

Construct event sources

Function Compute provides a variety of triggers such as OSS triggers, Log Service triggers, and CDN event triggers. To simulate the Function Compute environment, you must construct trigger events when you run or debug functions locally.

A trigger event can be a set of readable JSON configurations or non-readable binary data. The following example displays a JSON event:

  1. {
  2. "testKey": "testValue"
  3. }

You can use one of the following methods to pass the event to your function:

  1. Pipe: echo ‘{“testKey”: “testValue”}’ | fun local invoke nodejs8
  2. File: Create a JSON file, for example, event.json, to store the JSON event. Use -e to specify the file name in the command: fun local invoke -e event.json nodejs8
  3. Redirection: fun local invoke nodejs8 < event.json or fun local invoke nodejs8 <<< ‘{“testKey”: “testValue”}’. For more information, visit Bash Input Redirection.

fun local start

Syntax

You can use fun local start -h to view the help information of the fun local start command:

  1. Usage: fun local start [options]
  2. Allows you to run the Function Compute application locally for quick development & testing.
  3. It will start an http server locally to receive requests for http triggers and apis.
  4. It scans all functions in template.yml. If the resource type is HTTP, it will be registered to this http server, which can be triggered by the browser or some http tools.
  5. For other types of functions, they will be registered as apis, which can be called by sdk in each language or directly via api.
  6. Function Compute will look up the code by CodeUri in template.yml.
  7. For interpreted languages, such as node, python, php, the modified code will take effect immediately, without restarting the http server.
  8. For compiled languages ​​such as java, we recommend you set CodeUri to the compiled or packaged location.
  9. Once compiled or packaged result changed, the modified code will take effect without restarting the http server.
  10. Options:
  11. -d, --debug-port <port> specify the sandboxed container starting in debug mode, and exposing this port on localhost
  12. -c, --config <ide/debugger> output ide debug configuration. Options are vscode
  13. -h, --help output usage information

Run HTTP trigger functions locally

The syntax to run an HTTP trigger function is as follows:

  1. fun local start [options]

where the option is optional.

When the fun local start command is run, Fun starts an HTTP server to provide HTTP services. Then, Fun registers functions that are described in template.yml and configured with HTTP triggers with the HTTP server. After registration, you can run the functions by using browsers or other HTTP tools.

For example, all HTTP trigger information will be displayed after you run fun local start under the local_http path:1You can trigger an HTTP trigger function to run by using the corresponding URL.

The following example shows how to trigger an HTTP trigger function in the Node.js runtime. This process also applies to Python and PHP functions.2

Debug HTTP trigger functions locally

You can use -d and—debug-port to debug HTTP trigger functions locally. The process is similar to the function trigger process. You can also use -c and —config to display the integrated development environment configurations.

To debug a function, you must use fun local start —debug 3000 —config vscode to start a service. The following result indicates all functions in template.yml are registered.3

Select a URL based on the service name, function name, or HTTP trigger name and open the URL with a browser. The browser generates no responses, and the terminal displays the log:

  1. skip pulling image aliyunfc/runtime-python3.6:1.2.0...
  2. you can paste these config to .vscode/launch.json, and then attach to your running function
  3. ///////////////// config begin /////////////////
  4. {
  5. "version": "0.2.0",
  6. "configurations": [
  7. {
  8. "name": "fc/local-http-demo/python3",
  9. "type": "python",
  10. "request": "attach",
  11. "host": "localhost",
  12. "port": 3000,
  13. "pathMappings": [
  14. {
  15. "localRoot": "/Users/tan/fun_local_http_demo/python3",
  16. "remoteRoot": "/code"
  17. }
  18. ]
  19. }
  20. ]
  21. }
  22. ///////////////// config end /////////////////
  23. FunctionCompute python3 runtime inited.
  24. FC Invoke Start RequestId: 04c57fba-cbe9-4c1f-8c57-f8e0b539fa08

Copy the configurations from the log to the Visual Studio Code debugger, create breakpoints, and click the start debugging icon.

The following example shows how to debug an HTTP trigger function in Python. This process also applies to Node.js and PHP functions.5

Perform hot load

A hot load is performed when you run and debug HTTP trigger functions locally.

If you have started a service locally by using fun local start, you can refresh the web page or trigger the function again to run the modified function rather than reloading the local service.

The following example shows the hot load result of a Node.js function. This process also applies to PHP and Python functions.

Note: You must run npm install in the function directory in advance to initialize the Node.js modules on which the function depends.7

Use API operations to run and debug functions locally

The syntax is the same as the syntax to run an HTTP trigger function:

  1. fun local start [options]

where the option is optional.

When the fun local start command is run, Fun starts an HTTP server to provide HTTP services. Then, Fun registers functions that are described in template.yml and not configured with HTTP triggers with the HTTP server. After registration, you can call the functions by using InvokeFunction API operations or SDKs.

Signature authentication must be performed if you call functions by using API operations. We recommend that you use SDKs to call functions.Use fun local start to run a service. The log is displayed as follows:

  1. $ fun local start
  2. api localdemo/php72 was registered
  3. url: http://localhost:8000/2016-08-15/services/localdemo/functions/php72/invocations/
  4. api localdemo/python27 was registered
  5. url: http://localhost:8000/2016-08-15/services/localdemo/functions/python27/invocations/
  6. api localdemo/python3 was registered
  7. url: http://localhost:8000/2016-08-15/services/localdemo/functions/python3/invocations/
  8. api localdemo/nodejs6 was registered
  9. url: http://localhost:8000/2016-08-15/services/localdemo/functions/nodejs6/invocations/
  10. api localdemo/nodejs8 was registered
  11. url: http://localhost:8000/2016-08-15/services/localdemo/functions/nodejs8/invocations/
  12. api localdemo/java8 was registered
  13. url: http://localhost:8000/2016-08-15/services/localdemo/functions/java8/invocations/
  14. function compute app listening on port 8000!

You can use the Function Compute SDK for Python to call functions after the service is started.

Use the following command to install the Function Compute SDK for Python:

  1. pip install aliyun-fc2

Enter the following code:

  1. import fc2
  2. client = fc2.Client(endpoint='http://localhost:8000', accessKeyID='<your access key id>', accessKeySecret='your access key secret')
  3. resp = client.invoke_function('localdemo', 'php72')
  4. print resp.headers
  5. print resp.data

Note: The AccessKey IDs and AccessKey secrets configured in the SDK code and Fun must be consistent. Otherwise, the signature authentication will fail when you call functions.

The execution result is displayed as follows:7

Related configurations

Use fun local invoke to access a service on the host

If you are using Docker 18.03 and later for Mac or Windows, you can use host.docker.internalas the IP address to access your local service. For example:

  1. client = fc2.Client(endpoint='http://host.docker.internal:8000', accessKeyID='xxx', accessKeySecret='xxx')
  2. resp = client.invoke_function('localdemo', 'nodejs8', json.dumps({'code': 123}))

If you are using a version earlier than Docker 18.03, you can run ifconfig for Linux or Mac or ipconfig for Windows on the host to view the host IP address and then configure the IP address to the endpoint.

Environment variables

Environment variables configured in template.yml are consistent as those in the Function Compute environment. You can use code to obtain the variables when functions are running. For more information, see Environment variables.

Apart from the environment variables provided by the EnvironmentVariables property, Fun provides the local=true environment variable to identify functions that are run in the local environment.

You can use this environment variable for specific logic processing.

Credentials

You can use the AccessKey pair stored in credentials to access other services provided by Alibaba Cloud. fun local and fun deploy commands use the same method to search AccessKey pair.

For more information about Function Compute credentials, see Context(52699).

The following code shows how to configure an OSS client by using credentials in local and Function Compute environments:

  1. local = bool(os.getenv('local', ""))
  2. if (local):
  3. print 'thank you for running function in local!!!!!!'
  4. auth = oss2.Auth(creds.access_key_id,
  5. creds.access_key_secret)
  6. else:
  7. auth = oss2.StsAuth(creds.access_key_id,
  8. creds.access_key_secret,
  9. creds.security_token)