Function Logs | Yext Hitchhikers Platform

Function logs allow users to view details about each function execution in their account. As a refresher, developers can write Typescript functions to be hosted and run within Yext to enact custom logic. These serverless functions can be called from a variety of systems throughout the platform, including Pages, Connectors, or Serverless Functions in Apps, which all have their logs accessible.

This doc details the interfaces through which users can view and interact with function logs, and provides details about the events, which are recorded as function invocations and function fetches.

Function Logs UI

The Function Logs UI offers a split-screen view, where the left side contains a row for single function invocation, and the right side contains details for the selected invocation. Invocations are listed in descending chronological order, grouped by date.

Left Panel - Function Invocations

Each invocation is listed as a row on the left hand side of the Functions table. Information is displayed per row in the following order

Information Limits and Validations
Status (for source and transform) Whether the invocation was a success or failure. Failures include system wide errors, where the function was not properly invoked, or any uncaught errors that occurred as a result of your function invocation.

If any invocation error is present, the status will be Failure.
Plugin ID The ID of the plugin that contains the function that was invoked.
Function Name The name of the function that was invoked
Caller The system that called (or “invoked”) the function. This may be Pages, Connector Transform, Connector Source, Serverless Functions in Apps, or any other system that can invoke a function.
Timestamp The timestamp of function invocation. All rows are grouped by date and appear in descending order (most recent invocations appearing at the top of the table)

Right Panel - Details per Function Invocation

Details about the selected invocation are listed on the right hand side. There are 5 tabs containing a set of details for the invocation.

Information Description
Invocation UID The system-generated unique ID of the function invocation.
Region The data region that the function was invoked in.
Queue Duration The length of time that the function existed in the queue,
Argument Bytes The size of the argument passed to the function, in bytes.
Argument JSON The JSON argument that was passed to the function.

Runtime

The Runtime tab includes details about the actual runtime of the function.

Information Description
Load Duration The duration (in milliseconds) it took to load the Function and various dependencies before the runtime began. Not counted against the invocation time limit.
Runtime Duration The duration (in milliseconds) that the function spent running.
Logs Any console logs that the function produced during the run (e.g. any data written via console.log, console.warn, or console.error). This will include any caught errors. Uncaught errors will be displayed in the errors section under the Response tab.

Response

The Runtime tab includes details about the response returned by the function.

Information Description
Result Bytes The size of the result output by the function, in bytes
Result JSON The JSON object returned by the function.
Errors Any uncaught errors or invoking-system errors that occurred as a result of the function invocation.

Caller Details

The caller details tab includes any details about your function specific to the calling system. For example, this might include the information about the Connector that invoked the function, or deploy information if invoked by our Pages system. The details here will vary from caller to caller. Callers today include:

  • Connector Transform
  • Connector Source
  • Search Query Rule
  • Pages HTTP Function
  • Pages “Event-Driven” Function
  • Webhook

Function Fetches

A “Function Fetch” is an HTTP request made within your function’s execution. For each fetch, the details below will be provided.

NOTE: any HTTP requests made to download packages are not included. Specifically, if you import from a CDN, the import will not be included as a fetch for the given function invocation.

Information Description
Fetch UID The unique ID associated with the fetch.
Fetch Timestamp The timestamp that the fetch was executed.
URL The URL where the fetch was sent.
HTTP Method The HTTP method used for the fetch.
Duration The total duration (in milliseconds) of the fetch.
Request Bytes The size of the fetch request, in bytes
Response Bytes The size of the response of the fetch, in bytes.
Status Code The HTTP status code of the request.
Error Message Any error messages provided in the response of the fetch (if any).

Filtering

The function logs table can be filtered by the following properties:

Information Description
Property Filter Type
Status Success / Failure
Plugin ID “Contains” search
Function Name “Contains” search
Invocation UID “Matches” search
Caller Multi-select
Caller Details Key/Value Pair

True if the specified key CONTAINS the specified value

Multiple pairs are AND joined
Timestamp Time range
Search JSON Search for text contained in EITHER the Argument, Logs, or Result JSON.

When filtering using the Search JSON property, the text must be constrained to either a key or a value in the JSON. For example, if the JSON is:

{
   “name”: “John Smith”,
}

The following searches would return this function invocation:

  • John Smith
  • John
  • hn Smith
  • name

However, the following searches would return no results:

  • "name": "John"
  • "name": "John Smith"

Function Logs in the Logs API

Function logs can be accessed by querying two different tables in the POST query endpoint of the Logs API: 1. functionInvocations table: contains all invocation details, including general, runtime, response, and caller information. 2. functionFetches table: contains all function fetches details.

Before doing this, you will need to configure an app in the Developer Console and set the Logs endpoint permissions to Read-Only. You will also need your API Key.

Below are a sample request and payload, and a sample response from the Logs endpoint.

Function Invocations

Request Example: POST https://api.yext.com/v2/accounts/{businessID}/logs/tables/functionInvocations/query?api_key={apiKey}&v={YYYYMMDD}

Payload Example:

{
 "fields": ["*"],
 "pageSize": 1,
 "filter": "functionName.containsAnyCase('myfunction')"
}

Response Example:

{
   "meta": {
       "uuid": "uuid",
       "errors": []
   },
   "response": {
       "logRecords": [
           {
               "accountId": 123,
               "caller": {
                   "id": "CONNECTOR_TRANSFORM"
               },
               "functionName": "_generateBusinessDescription",
               "invocationDetails": {
                   "argument": {
                       "bytes": 267,
                       "json": {
                           "docs": [
                               {
                                   "$key": {
                                       "locale": "",
                                       "primary_key": "81490299"
                                   },
                                   "id": "test12",
                                   "name": "My awesome placee"
                               }
                           ],
                           "meta": {
                               "appSpecificAccountId": "df5f0e0e077279cae084ef53bb1ffc37028a7818",
                               "eventType": "RECORD",
                               "timestamp": 1676491750218,
                               "uuid": "06e8cefc-b1e7-4c1e-91c0-263ad557f1f0"
                           }
                       }
                   },
                   "queueDuration": 2,
                   "region": "NJ1",
                   "timestamp": "2023-02-15 20:09:10.253",
                   "uid": "01GSBB3YVDTNH3QVR89NGMNE0C"
               },
               "pluginId": "generate-business-descriptions",
               "responseDetails": {
                   "bytes": 156,
                   "json": {
                       "meta": {
                           "errors": [
                               {
                                   "code": 2246,
                                   "message": "Entity not found: undefined",
                                   "type": "FATAL_ERROR"
                               }
                           ],
                           "uuid": "018656b2-1f24-a0ac-2700-9b7cc5fe51c7"
                       },
                       "response": {}
                   }
               },
               "runtimeDetails": {
                   "loadDuration": 240,
                   "logs": [
                       {
                           "level": "INFO",
                           "message": "docs {\n  docs: [ { '$key': [Object], id: 'test12', name: 'My awesome placee' } ],\n  meta: {\n    uuid: '06e8cefc-b1e7-4c1e-91c0-263ad557f1f0',\n    timestamp: 1676491750218,\n    appSpecificAccountId: 'df5f0e0e077279cae084ef53bb1ffc37028a7818',\n    eventType: 'RECORD'\n  }\n}\n",
                           "timestamp": "2023-02-15T20:09:10.503Z"
                       },
                       {
                           "level": "INFO",
                           "message": "webhookdoc undefined\n",
                           "timestamp": "2023-02-15T20:09:10.505Z"
                       },
                       {
                           "level": "INFO",
                           "message": "\n",
                           "timestamp": "2023-02-15T20:09:10.505Z"
                       },
                       {
                           "level": "INFO",
                           "message": "This is my prompt: \n\nRewrite the input information in the format of a 3 paragraph business description.\n\n#Input Information:\n- Company Name: undefined\n- Address: \n- Keywords: \n\n#Requirements:\n- Write 3 Paragraphs\n- Write less than 750 characters\n- Do not use links or URLs\n- Do not include misleading information\n\nUse this format, replacing text in brackets with the result. Do not include the brackets in the output: \n3 Paragraph Business Description (less than 750 Characters)\n\n[Introduction paragraph mentioning the city the company serves]\n\n[Paragraph about the products and services]\n\n[Paragraph with a call to action]\n\n#Example:\nWe at Rachel's Awesome Car Dealer are proud to be your go-to car dealership in Closter, NJ. We offer an extensive selection of new and used vehicles, as well as repair services for all makes and models. \n\nFrom cars and trucks to vans and SUVs, our knowledgeable staff is here to help you find the perfect vehicle for you. We also have an on-site service department to help with any maintenance and repair needs you may have. \n\nAt Rachel's Awesome Car Dealer, we strive to provide our customers with the best service possible. Stop by today and let us help you find the car of your dreams.\n\n#Output:\n3 Paragraph Business Description (less than 750 Characters)\n\n\n",
                           "timestamp": "2023-02-15T20:09:19.311Z"
                       },
                                              {
                           "level": "INFO",
                           "message": "fetch api.openai.com result=OK id=01GSBB3YVDTNH3QVR89NGMNE0C duration=8.805s sent=1.4 kB recieved=748 B",
                           "timestamp": "2023-02-15T20:09:19.313Z"
                       },
                       {
                           "level": "WARN",
                           "message": "fetch api.yext.com result=NotFound Not Found id=01GSBB3YVDTNH3QVR89NGMNE0C duration=0.126s sent=501 B recieved=156 B",
                           "timestamp": "2023-02-15T20:09:19.440Z"
                       }
                   ],
                   "runtimeDuration": 8946
               },
               "status": null
           }
       ],
   }
}

Function Fetches

Request Example: POST https://api.yext.com/v2/accounts/{businessID}/logs/tables/functionFetches/query?api_key={apiKey}&v={YYYYMMDD}

Payload Example:

{
   "fields" : ["*"],
   "pageSize": 10,
   "descending": "true",
   "filter": "invocation.uid == '01GSBB3YVDTNH3QVR89NGMNE0C'"
}

Response Example:

{
   "meta": {
       "uuid": "0186dc9f-e5e6-c612-35e7-90d2145f47bf",
       "errors": []
   },
   "response": {
       "logRecords": [
           {
               "fetchTimestamp": "2023-02-15T20:09:19.314Z",
               "fetchUid": "01GSBB47TXKXWG17V48ZAGQMDR",
               "accountId": 3859762,
               "baseUrl": "https://api.yext.com",
               "errorMessage": "Not Found",
               "fetchDuration": 126,
               "httpMethod": null,
               "invocation": {
                   "pluginId": "generate-business-descriptions",
                   "uid": "01GSBB3YVDTNH3QVR89NGMNE0C"
               },
               "request": {
                   "bytes": 156
               },
               "response": {
                   "bytes": 501
               },
               "statusCode": 5
           },
           {
               "fetchTimestamp": "2023-02-15T20:09:10.508Z",
               "fetchUid": "01GSBB47TXN7XPDX3SBXGSHWFT",
               "accountId": 3859762,
               "baseUrl": "https://api.openai.com",
               "errorMessage": "",
               "fetchDuration": 8805,
               "httpMethod": null,
               "invocation": {
                   "pluginId": "generate-business-descriptions",
                   "uid": "01GSBB3YVDTNH3QVR89NGMNE0C"
               },
               "request": {
                   "bytes": 748
               },
               "response": {
                   "bytes": 1438
               },
               "statusCode": 0
           }
       ]
    }
}

Logs API vs UI

Stipulation Function Logs via Logs API Function Logs UI
Requires Developer App Yes No
Filterable Yes Yes (More Limited)
Invocations Maximum Page Size (total records returned per request/page) 1,000 (50 default) 20 (per “Load More” click)
Function Fetches Maximum Page Size (total records returned per request/page) 1,000 (50 default) 50

Function Logs Limitations

  • Function Logs UI and API is limited to data from the last 30 days.
  • It may take up to 5 minutes for new update logs to appear in the UI and Logs API.
  • If a value is truncated, “” will appear in the UI/API
    • Truncation occurs when the entire invocation exceeds 1MB. The system will begin truncating data, starting with Logs, then the Error Response, Status, Result… until the entire invocation is under 1MB. Any line items that are truncated will be replaced with “