AppEngine Functions (Serverless Functions)

Please note that invocation of AppEngine Functions can trigger the ingest (and therefore implicitly the retention) of additional data or the execution of a DQL query. This might generate additional consumption of Ingest & Process, Retain, and Query dimensions, depending on the use cases.

Here's what's available to assist you in understanding your organization's consumption of AppEngine Functions:

Concept

Explanation

Works out-of-the-box

No external hosting required, no need to worry about maintaining a runtime environment to execute logic or code

Extend the platform

  • Fetch data (not persisted in Grail) live from external APIs
  • Connect to APIs in the cloud and on premises (with EdgeConnect)
  • Dedicated APIs to push data from external systems
  • Custom APIs with specific semantics

Data processing

  • Data processing, for example, to aggregate data persisted in Dynatrace and external data
  • Data transformation to make external and aggregated data easily consumable within the Dynatrace web UI
  • Connect apps with external databases and normalize data for immediate platform-wide use

Enterprise readiness; Secure analytics (run-time)

  • No firewall or network configuration changes necessary for incoming connections
  • Secure and sandboxed execution in the context of your existing policies
  • Authentication and authorization (permission handling)

AppEngine functions are deployed in an environment with 256 MiB RAM and can have a maximum execution time of up to 120 seconds. This differs from the following variants of AppEngine (Serverless) Functions:

  • App functions
    These functions represent the backend of an app and are built, bundled and deployed together with your custom app.

  • Ad hoc functions
    Custom code to accomplish specific use cases is referred to as ad hoc functions (or "glue" code). These functions can be invoked from within Notebooks, Dashboards, Workflows, or directly via API.

  • Custom actions
    App functions that, together with a UI component, can be declared as a custom Workflows action to extend the Workflows app. Custom actions can then be selected as a task within the Workflows app and be executed within the Workflows.

Billable consumption of AppEngine functions occurs when:

  • Invoking App Functions in a custom app
  • Invoking ad-hoc functions from within Notebooks, Dashboards, Workflows or directly via API
  • Invoking custom actions

The unit of measure for consumption of AppEngine Functions is an invocation. One invocation is consumed for each minute (including partial minutes) of function execution time. The total consumption is calculated by multiplying the number of invocations by your rate card price per invocation.

Example

  • You add a code section in your Notebook and add custom code, which we refer to as an "Ad-hoc function." The execution of the function takes 45 seconds. This consumes 1 function invocation.
  • In your custom app you include an app function to retrieve data from your data source. The execution time of this function is 72 seconds. This consumes 2 invocations (as 2 minutes were started during function execution).

Consumption details

To help you understand and analyze your organization's consumption of AppEngine Functions - Small, Dynatrace provides usage details that can be queried via DQL, for example, in Notebooks or via the Environment API. Relevant queries are also available in Account Management (Usage summary > AppEngine Functions - Small > Actions > View details).

While you can link directly to your Dynatrace environment from Account Management, you can also copy and paste DQL queries into a notebook to analyze consumption of AppEngine Functions. The following DQL query provides an overview of daily AppEngine Function invocations by function type:

fetch dt.system.events, scanLimitGBytes: -1
| filter event.type == "AppEngine Functions - Small" AND event.kind == "BILLING_USAGE_EVENT" AND billing_type == "BILLABLE"
| fieldsAdd data = if(matchesPhrase(function.type, "AD_HOC"), "Ad-hoc", else: if(matchesPhrase(function.type, "ACTION"), "Actions", else: if(matchesPhrase(function.type, "STANDARD"), "App functions")))
| summarize billed_invocations = takeAny(billed_invocations), by:{timestamp=bin(timestamp, 1d), event.id,data}
| summarize invocations = sum(if(billed_invocations,billed_invocations,else:1)), by:{data, timestamp}
| sort timestamp desc, invocations desc

The following DQL query provides details on users and apps using AppEngine Functions: fetch dt.system.events, scanLimitGBytes:

fetch dt.system.events, scanLimitGBytes: -1
| filter event.type == "AppEngine Functions - Small" AND event.kind == "BILLING_USAGE_EVENT" AND billing_type == "BILLABLE"
| summarize billed_invocations = takeAny(billed_invocations), by:{startHour = bin(timestamp, 1h), event.id, user.email, caller.app.id}
| summarize Invocations = sum(if(billed_invocations,billed_invocations,else:1)), by:{User = user.email, Calling_App = caller.app.id}
| sort Invocations desc