X

Best Practices from Oracle Development's A‑Team

  • May 5, 2021

OCI Serverless Functions Tracing with APM

With the release of Distributed Tracing for Oracle Functions and APM (Application Performance Monitoring) on Oracle Cloud Infrastructure (OCI) we will try to explore end-to-end performance of Serverless Functions using APM's Distributed Tracing and Real User Monitoring.

APM features

We will be using the following APM features for this use case:

Real User Monitoring: Provides an insight into the experience of the end user directly from the browser. Real User Monitoring identifies performance degradation by monitoring page load time and user action. It enables complete end-user support by tracking user sessions.

Distributed Tracing: Collects and processes transaction instance trace data using Application Performance Monitoring data sources, open-source tracers, or directly using API. Distributed Tracing monitors transaction performance, volume, and error rate and notifies you of issues. It analyzes load, usage patterns, performance, and capacity across out-of-the-box and custom dimensions.
 

Tracing Functions with APM Use Case

Summary

We will have a static web page (index.html) inside the object storage bucket. This website is instrumented to send the trace data onto APM domain. User will try load it using the browser and click on "Fetch Products", which then makes an ajax call to Oracle Functions via OCI API gateway. The Backend Oracle Functions app will query the database and fetch the details of the products. The Browser to Oracle Functions traces will be sent to APM and the traces will then be analyzed using APM trace explorer in OCI console.

We also enable functions tracing by using the toggle switch in the Functions section of the Console and select an APM Domain. When your function is invoked, the Functions service automatically sends a default Function Invocation span to the selected APM Domain, without any tracing code in your function. This default span captures the overall time taken by the Functions service, from the time it receives an invocation request until it sends a response back to the invoker, including cold start time and errors returned by the service.

Together they provide an end-to-end performance visibility into the application.
 

ATP Database

  • Create an Autonomous Transaction Processing (ATP) Database
  • Click on OCI Console -> Autonomous Database -> DB Connection and download the wallet, you will need it at next stage.
  • Access the ATP Service Console -> SQL Developer Web and perform the following actions:
CREATE USER test_user IDENTIFIED BY default_Password1;

GRANT CREATE SESSION TO test_user;
GRANT UNLIMITED TABLESPACE TO test_user;
CREATE ROLE test_role;
GRANT test_role TO test_user;

CREATE TABLE test_user.products (
brand VARCHAR2(20),
title VARCHAR2(40),
description VARCHAR2(500)
);

GRANT SELECT, INSERT, UPDATE, DELETE ON test_user.products TO test_role;

INSERT INTO test_user.products VALUES ('Oracle','OCI','Oracle Cloud Infrastructure');
INSERT INTO test_user.products VALUES ('Google','GCP','Google Cloud Platform');
INSERT INTO test_user.products VALUES ('Microsoft','Azure','Microsoft Azure Cloud');

select brand,title from test_user.products;

BRAND		     TITLE
-------------------- ----------------------------------------
Oracle		         OCI
Google		         GCP
Microsoft		     Azure

OCI Functions

  • Upgrade to the latest fn CLI
  • Create a Functions Application
  • Add configuration variables (DB_USER, DB_PASSWORD and CONNECT_STRING) to Functions application.
            $ fn config app 'functions-app-name' DB_PASSWORD ''db-password''
    	    $ fn config app 'functions-app-name' config DB_USER ''db-user''
            $ fn config app 'functions-app-name' config CONNECT_STRING 'CONNECT STRING FROM tnsnames.ora,ex: demodb_tp,   
              demodb_medium etc'
         
  • Clone this github repository:
    $ git clone https://github.com/naikvenu/oci-fn-apm-example
    $ cd oci-fn-apm-example
    
    • Extract the wallet downloaded in the previous step under wallet folder
                 $ ls wallet/ 
                README ewallet.p12 ojdbc.properties tnsnames.ora 
                cwallet.sso keystore.jks sqlnet.ora truststore.jks
                
    • Deploy the Fn application onto OCIR registry

  • Note : If using Fn commands is new to you, then refer OCI Fn quickstart for help.
    $ cd oci-fn-apm-example/
    $ fn -v deploy --app demo-fn
    
  • Add this IAM policy on the tenancy :
            Allow service faas to use apm-domains in tenancy
        

OCI API Gateway

  • Create an API gateway
  • Create an API gateway deployment and follow the noted settings for CORS

  • IAM policy for API GW to use OCI functions
        ALLOW any-user to use functions-family in compartment acme-functions-compartment where ALL {request.principal.type= 'ApiGateway', request.resource.compartment.id = 'ocid1.compartment.oc1..aaaaaaaa7______ysq'}
        
  • API Gateway communicates on port 443, which is not open by default. You have to add a new stateful ingress rule for the regional subnet to allow traffic on port 443.
    Click the name of the regional subnet, then the name of the default security list, and then click Add Ingress Rules and enter the following:
        Source Type: CIDR
        Source CIDR: 0.0.0.0/0
        IP Protocol: TCP
        Source Port Range: All
        Destination Port Range: 443
    Click Add Ingress Rules to add the new rule to the default security list. 
    

APM Domain

  • Create an APM Domain
  • Make a note of the Data Upload Endpoint and Public Data Key. These are required during instrumentation of index.html file

Enable Functions Distributed tracing

  • Enable OCI Functions Application tracing `Developer Services -> Functions -> Applications -> Traces` Enable traces and Select the Application Performance Monitoring Domain.
  • Enable OCI Functions tracing `OCI Console -> Developer Services -> Functions -> Application -> Function -> Enable Trace

OCI Object Storage Bucket

$ cd oci-fn-apm-example 
$ ls 
index.html 
Note: Before uploading the index.html file, replace the items with details specific to your setup, for ex: your-api-gateway-address, APM Data Upload Endpoint and Public Data Key.
  • Finally, Create a OCI Object Storage Bucket and set the visibility to public
  • Upload the index.html

Access the Application

  • Fetch the URI of the index.html uploaded on the object storage.

    • Access the URI using the browser and Click on `Fetch Products`.

    • Access the OCI Console -> APM -> Trace Explorer and analyze the traces. From below you can see 3 traces: the connection to the HttpURL, Page Load and Partial Update a.k.a button click in our case

    • This is the partial update (button click) trace, which shows 3 spans

     

    • Details of the Ajax call made from the browser

Conclusion

We saw how APM helped to perform the end to end tracing for serverless applications. We specifically looked at Real User Monitoring and Distributed Tracing features of APM.

As a next step, we can further instrument the serverless application to emit custom child spans, using libraries like Zipkin to get more visibility into your code and downstream dependencies.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha