Set up logging and event sharing for an application

This topic describes how to set up logging and event sharing to troubleshoot an installed application.

This topic provides information on setting up logging and event sharing as a provider. Refer to Enabling Logging and Event Sharing for an Application for the consumer requirements for configuring this feature.

Logging and trace events allow you to collect information about an application to troubleshoot errors. Using logging and trace events, you can also get a better idea of how your application runs and improve your application later.

Workflow for setting up logging and event sharing as a provider

As a provider, you can set up logging and event sharing for an application by performing the following:

  1. Review the considerations for using logging and event sharing.

  2. Configure logging and trace events for functions and stored procedures.

  3. Set the log and trace level in the manifest file.

  4. Configure an account to store shared events.

After the consumer installs an application and enables logging and event sharing, you can view logging and event information shared by the installed application:

Considerations for using logging and event sharing

Before using logging and event sharing for an application, providers must consider the following:

  • Providers are responsible for all costs associated with event sharing on the provider side, including data ingestion and storage.

  • Providers must have an account to store shared events in each region where you want to support event sharing.

  • Providers must define the default log level and trace level for an application in the manifest file.

Note

Event sharing cannot be enabled for an app that is installed in the same account as the application package it is based on. To test event sharing for an app, a provider must use multiple accounts.

Configure logging and trace events in functions and procedures

The Native Apps Framework requires an event table to store log messages and trace events generated from functions and stored procedures in an application.

Note

If the consumer of an application does not set up an event table and make it the active table before installing the application, event and logging data are discarded.

An account can have multiple event tables, but only one of them can be set as the active event table for a Snowflake account at a time. Without an active event table, log messages and trace events generated by the application are not captured. This is true even if the functions and procedures in an application call the logging and trace event APIs.

To create an event table, use the CREATE EVENT TABLE command. For more information, see Setting up an Event Table.

After code has recorded log messages and trace events, a provider can query recorded data.

For information about recording and querying log and trace data, see the following:

Set the log and trace level in the manifest file

To set the default log and trace event levels for a version of an application, set the log_level and trace_level parameters in the manifest file as shown in the following example:

artifacts:
  setup_script: setup.sql
configuration:
  trace_level: OFF
  log_level: DEBUG
Copy

When a provider enables tracing, a Snowflake Native App automatically captures the start and end times for all queries and stored procedure calls.

Note

Publishing a Snowflake Native App with the trace_level property set to a value other than OFF might expose calls to hidden stored procedures to any user in the consumer account who can view the event table.

See Setting trace level and Setting log level for information on supported values for trace_level and log_level.

When the Snowflake Native App is initially installed, it uses the log levels defined in the manifest file. If the log level is changed in a subsequent upgrade, the new log level takes effect after the upgrade process completes.

The log and trace level can only be set within the manifest file. The consumer is not allowed to modify the log level using the ALTER APPLICATION or ALTER DATABASE commands.

Similarly, any session level settings for the logging level are ignored by the application.

Configure an account to store shared events

To store shared logs and events, a provider must select an account to hold an event table. This can be any account that a provider can access. However, if an organization has multiple providers publishing application packages, consider using a Snowflake account that is dedicated to storing shared events from the consumer.

The following restrictions apply to accounts used to store shared events:

  • You must use the ORGADMIN role to set an account as the account used to store events.

  • The account must have an active event table.

  • The specified account cannot be any of the following:

    • A locked or suspended account.

    • A reader account.

    • A trial account.

    • A Snowflake managed account.

Note

A provider can collect logs and shared events only in the same region where a consumer installs an application. Providers must set up an account to store shared events in every region where consumers configure event sharing for an application.

Set an account as the events account

To set an account to be the events account for a region, call the SYSTEM$SET_EVENT_SHARING_ACCOUNT_FOR_REGION system function:

CALL SYSTEM$SET_EVENT_SHARING_ACCOUNT_FOR_REGION('<snowflake_region>', '<region_group>', '<account_name>')
Copy

Where:

snowflake_region

Specifies the region where the account is located, for example: AWS_US_WEST_2, AWS_US_EAST_1.

region_group

Specifies the region group, for example: PUBLIC. Refer to Region groups for details.

account_name

Specifies the account name. If another account is already set as the events account in the specified region, running this command changes the events account to be the account specified here.

Un-set an account as the events account

To unset an account to be the events account for a region, call the SYSTEM$UNSET_EVENT_SHARING_ACCOUNT_FOR_REGION system function:

CALL SYSTEM$UNSET_EVENT_SHARING_ACCOUNT_FOR_REGION('<snowflake_region>', '<region_group>', '<account_name>')
Copy

Where:

snowflake_region

Specifies the region where the account is located, for example: AWS_US_WEST_2, AWS_US_EAST_1.

region_group

Specifies the region group, for example: PUBLIC.

account_name

Specifies the account name.

View event accounts in the provider’s organization

To show events accounts in a provider’s organization, call the SYSTEM$SHOW_EVENT_SHARING_ACCOUNTS system function:

CALL SYSTEM$SHOW_EVENT_SHARING_ACCOUNTS()
Copy

Note

You must use the ORGADMIN role to call this function.

This system function returns a string in JSON format containing a list of event accounts within the organization. Because the metadata takes some time to propagate to all regions, this function might experience some delay when showing latest events account after the user set/unset an events account for the organization.

View the logging and trace event levels defined in an application package

Use the DESCRIBE APPLICATION command to view the logging level of an installed application, as shown in the following command:

DESC APPLICATION HelloSnowflake;
Copy

Use the SHOW VERSIONS command to view the logging level the application versions defined in an application package, as shown in the following example:

SHOW VERSIONS
  IN APPLICATION PACKAGE HelloSnowflake;
Copy

View the logs and events in the event table

To view the logs and events stored in the event table, use the SELECT command as shown in the following example:

SELECT * FROM EVENT_DB.EVENT_SCHEMA.MY_EVENT_TABLE
Copy

Shared event information available to the provider

The following sections describe the information that the Native Apps Framework shares with providers.

Application event context shared with the provider

To help providers easily identify the source of the shared events, the following fields are populated into the RESOURCE_ATTRIBUTES column of the event table when they are shared with the provider:

  • snow.application.package.name

  • snow.application.consumer.organization

  • snow.application.consumer.name

  • snow.listing.name

  • snow.listing.global_name

Fields that are not shared with the provider

To protect consumer information, the following fields from the RESOURCE_ATTRIBUTES column are not shared with provider:

  • snow.database.id

  • snow.database.name

  • snow.schema.id

  • snow.executable.id

  • snow.owner.name

  • snow.owner.id

  • snow.warehouse.name

  • snow.warehouse.id

  • snow.query.id

  • snow.session.id

  • snow.session.role.primary.name

  • snow.session.role.primary.id

  • snow.user.name

  • snow.user.id

  • db.user

Instead of directly sharing the snow.database.name and snow.query.id fields with the provider, Snowflake shares the hash values (SHA-1) of these two fields as the following fields:

  • snow.database.hash

  • snow.query.hash

Snowflake provides the SHA-1 function used to mask these attributes. Consumers can calculate the hash values for the database name and query id, and use them as reference values when contacting the provider.

Determine if event sharing is enabled in the consumer account

In some contexts, a provider may need to determine if event sharing has been enabled in a consumer account. For example, a provider may need to disable app functionality if the event table is not available.

To determine if event sharing is enabled in a consumer account, providers can call the following system functions when defining the app logic:

  • IS_APPLICATION_SHARING_EVENTS_WITH_PROVIDER

    Returns TRUE if the app enables event sharing and an active event table is available in the consumer account. Returns FALSE, otherwise.

  • IS_APPLICATION_INSTALLED_FROM_SAME_ACCOUNT

    Returns TRUE if the app was installed in the same account as the application package it is based on. Returns FALSE otherwise.

Note

These system functions can only be called from within an app. See Determine if event sharing is enabled using the Python Permission SDK and Determine if event sharing is enabled using SQL

Determine if event sharing is enabled using the Python Permission SDK

The Python Permission SDK provides the following functions to determine if even sharing is enabled in a consumer account:

  • is_event_sharing_enabled()

    Returns TRUE if the SHARE_EVENTS_WITH_PROVIDER property is true and the consumer account has an active event table configured. Returns FALSE, otherwise.

  • is_application_local_to_package()

    Returns TRUE if the application is in the same account as the application package. Returns FALSE, otherwise.

Determine if event sharing is enabled using SQL

The following example shows how to call a stored procedure when event sharing is enabled in the consumer account.

Consider the following SQL stored procedure that creates a function to calculate the sum of two numbers:

CREATE OR ALTER VERSIONED SCHEMA app_schema;

CREATE OR REPLACE PROCEDURE app_schema.hidden_sum(num1 float, num2 float)
RETURNS FLOAT
LANGUAGE SQL
EXECUTE AS OWNER
AS $$
  DECLARE
    SUM FLOAT;
  BEGIN
    SYSTEM$LOG('INFO', 'CALCULATE THE SUM OF TWO NUMBERS');
    SUM := :NUM1 + :NUM2;
    RETURN SUM;
  END;
$$;
Copy

When added to the setup script of the app, these SQL commands create the hidden_sum stored procedure in the consumer account when the app is installed. However, this stored procedure is not visible to consumers because the USAGE privilege is not granted on the stored procedure to an application role.

The following example shows how you can use the values returned by the IS_APPLICATION_SHARING_EVENTS_WITH_PROVIDER and IS_APPLICATION_INSTALLED_FROM_SAME_ACCOUNT system functions to call the hidden_sum stored procedure.

CREATE OR REPLACE PROCEDURE app_schema.sum(num1 float, num2 float)
RETURNS STRING
LANGUAGE SQL
EXECUTE AS OWNER
AS $$
    BEGIN
      IF (SYSTEM$IS_APPLICATION_INSTALLED_FROM_SAME_ACCOUNT() or SYSTEM$IS_APPLICATION_SHARING_EVENTS_WITH_PROVIDER()) THEN
        CALL APP_SCHEMA.HIDDEN_SUM(:NUM1, :NUM2);
      ELSE
        -- notify consumers that they need to enable event sharing
        RETURN 'Sorry you can\'t access the API, please enable event sharing.';
      END IF;
    END;
$$;


CREATE APPLICATION ROLE IF NOT EXISTS ADMIN_ROLE;
GRANT USAGE ON SCHEMA APP_SCHEMA TO APPLICATION ROLE ADMIN_ROLE;
Copy

In this example, the sum stored procedure tests the values of the IS_APPLICATION_SHARING_EVENTS_WITH_PROVIDER and IS_APPLICATION_INSTALLED_FROM_SAME_ACCOUNT stored procedures. If one of their values is true, the sum stored procedure calls the hidden_sum stored procedure.

Request the event sharing from consumers using the Python Permission SDK

A provider can use the Python Permission SDK to create a Streamlit app to prompt consumers to enable event sharing in their account.

The SDK provides the request_event_sharing() method that displays a dialog in Snowsight that prompts the consumer to enable event sharing in their account. If the event table does not exist in the consumer account, the dialog allows the consumer to set the event table if they are using the ACCOUNTADMIN role.

Example: Using the Python Permission SDK with event tables

The following Streamlit example shows how to use the Python Permission SDK to do the following:

  • Determine if event sharing is enabled.

  • If event sharing is enabled, call the critical_feature_that_requires_event_sharing() function.

  • If event sharing is not enabled, call the request_event_sharing() function to display a dialog in Snowsight that prompts the consumer to enable event sharing.

import streamlit as st
import snowflake.permissions as permissions

def critical_feature_that_requires_event_sharing():
  st.write("critical_feature_that_requires_event_sharing")

def main():
  if permissions.is_event_sharing_enabled() or permissions.is_application_local_to_package():
     critical_feature_that_requires_event_sharing()
  else:
     permissions.request_event_sharing()

if __name__ == "__main__":
  main()
Copy

In this example, the critical_feature_that_requires_event_sharing() method is only called if one of the following is true:

  • Event sharing is enabled and the event table exists.

  • The Snowflake Native App is installed in the same account as the application package.

If neither condition is true, the Streamlit app calls the request_event_sharing() method which prompts the consumer to select an event table.

See Determine if event sharing is enabled in the consumer account for more information.