Registro e rastreamento para Streamlit in Snowflake

O Streamlit in Snowflake oferece suporte ao registro em log para tempos de execução de warehouse e de contêiner. Os tempos de execução de warehouse usam a estrutura de telemetria do Snowflake para capturar mensagens de log e rastrear eventos em uma tabela de eventos. Os tempos de execução de contêiner capturam os logs que seu app emite para saída padrão e erro padrão, armazenam esses logs na tabela de eventos da conta e fornecem logs ativos do console e exibições de logs históricos no Snowsight.

Ambos os tempos de execução armazenam logs na tabela de eventos no nível da conta. Um administrador de conta deve definir e configurar a tabela de eventos para que os logs possam ser capturados. Para obter instruções, consulte Visão geral da tabela de evento.

  • Para encontrar a tabela de eventos configurada para sua conta, execute:

    SHOW PARAMETERS LIKE 'event_table' IN ACCOUNT;
    
    Copy

A tabela a seguir compara o suporte a registro em log e rastreamento por tempo de execução:

Recurso

Tempo de execução de warehouse

Tempo de execução de contêiner (versão preliminar)

Registro em log da tabela de eventos

Com suporte

Com suporte

Rastreamento

Com suporte

Sem suporte

Logs ativos do console no Snowsight

Sem suporte

Com suporte

Logs históricos no Snowsight

Sem suporte

Com suporte

Registro em log no tempo de execução de contêiner

Os apps Streamlit de tempo de execução de contêiner são executados dentro de um contêiner Snowpark Container Services. O Snowflake captura automaticamente tudo o que seu app emite para saída padrão e erro padrão e o armazena na tabela de eventos da conta. É possível visualizar esses logs no Snowsight ou consultá-los com SQL.

Módulo de registro em log do Python

Use o módulo logging interno do Python para emitir mensagens de log do seu app. O exemplo a seguir configura um registrador que grava mensagens no nível INFO e em nível superior na saída padrão:

import logging
import sys

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(name)s: %(message)s",
    stream=sys.stdout,
)

LOGGER = logging.getLogger("my_app")
Copy

Na ordem do menos para o mais grave, o Python tem os seguintes níveis de registro em log:

  • DEBUG

  • INFO

  • WARNING

  • ERROR

Definir o nível como INFO captura mensagens INFO, WARNING e ERROR, mas não mensagens DEBUG.

Nota

Por padrão, o módulo logging do Python grava no erro padrão (sys.stderr). O Snowflake captura tanto a saída padrão quanto o erro padrão, de modo que seus logs sejam capturados independentemente do fluxo que você usa. Definir o fluxo como sys.stdout é opcional, mas recomendado porque o erro padrão é condicionalmente reservado para saída de erros.

Depois de configurar o registrador, você poderá usá-lo para registrar mensagens envolvendo todo o código do app. É comum definir um registrador em um módulo separado e importá-lo para o código do seu app:

source_directory/
├── my_logger.py
├── pyproject.toml
└── streamlit_app.py
Copy
import streamlit as st
from my_logger import LOGGER

LOGGER.info("Home page loaded")
st.title("My App")

if st.button("Run analysis"):
    LOGGER.info("Analysis button clicked")
    try:
        result = run_analysis()
        LOGGER.info("Analysis completed successfully")
    except Exception as e:
        LOGGER.error("Analysis failed: %s", e)
        st.error("Analysis failed: %s", e)
Copy

Logs ativos no Snowsight

Quando você edita um app de tempo de execução de contêiner no Snowsight, um painel de logs aparece abaixo do editor. Esse painel transmite as mensagens de log em tempo real conforme seu app as emite. Um pequeno histórico dos logs mais recentes é exibido quando você se conecta pela primeira vez.

Cada entrada de log mostra as seguintes informações:

Coluna

Descrição

Source

APP para logs do processo do Streamlit e registradores configurados pelo usuário, ou MANAGER para logs do processo do sistema que gerencia o contêiner.

Level

O nível de gravidade da mensagem de log (DEBUG, INFO, WARNING, ERROR).

Message

O conteúdo da mensagem de log.

Ações de log ativo disponíveis

No canto superior direito do painel de logs, é possível pesquisar e filtrar os logs para ajudar a encontrar as informações necessárias. Isso inclui pesquisa de texto, filtragem por fonte e filtragem por nível de gravidade. No menu de três pontos, você pode baixar os logs atuais, navegar até os logs históricos ou limpar o painel de registro ativo. Quando você limpa o painel, os logs atuais são excluídos da exibição atual, mas não da tabela de eventos. Um recarregamento imediato da página restaura os logs mais recentes.

Explicação das fontes de log

Os logs de apps de tempo de execução de contêiner têm uma de duas fontes:

  • MANAGER: o processo do sistema dentro do contêiner que prepara e executa seu app. Os logs do gerenciador incluem mensagens sobre como baixar os arquivos do seu apo da área de preparação, instalar as dependências do Python e iniciar o processo do servidor Streamlit. Se você atualizar os arquivos de dependência do seu app enquanto ele estiver em execução, o processo do gerenciador reinstalará as dependências e produzirá logs adicionais do gerenciador.

  • APP: logs do processo do servidor Streamlit em execução. Isso inclui mensagens de seus registradores Python configurados pelo usuário, do registrador interno do Streamlit e de qualquer outra saída que seu app grava na saída padrão ou no erro padrão.

O limite entre as fontes é o comando streamlit run. Tudo que o contêiner faz antes de iniciar o processo do Streamlit produz logs do MANAGER. Após o início do processo do Streamlit, a saída desse processo produzirá logs do APP.

Visualizar logs históricos no Snowsight

As etapas a seguir se aplicam somente a apps de tempo de execução de contêiner. Os apps de tempo de execução de warehouse não têm um painel de logs.

  1. Faça login no Snowsight.

  2. No menu de navegação, clique em Projects » Streamlit e selecione seu app.

  3. No canto superior direito da página, selecione Edit.

  4. No canto superior direito do painel de logs, selecione o menu de três pontos (Other actions) » Historical logs.

Esse procedimento abre a página de monitoramento do Snowpark Container Services para o serviço executado por seu app. A tabela de logs mostra as seguintes colunas:

Coluna

Descrição

Carimbo de data/hora

O carimbo de data/hora da mensagem de log.

ID da instância

O identificador da instância de contêiner. Ele é sempre 0 para apps Streamlit.

Contêiner

O identificador da instância de contêiner.

Fluxo

Se o log foi emitido para saída padrão (stdout) ou erro padrão (stderr).

Valor

A mensagem de log com formatação JSON que inclui os campos "level", "message", "source" e "timestamp".

Para obter mais informações sobre a página de monitoramento, consulte Snowpark Container Services: Serviços de monitoramento.

Consultar logs com SQL

Você pode consultar diretamente a tabela de eventos para analisar os logs do seu app de tempo de execução de contêiner. A consulta a seguir recupera os logs de um app Streamlit específico:

SELECT
    TIMESTAMP,
    RECORD['severity_text']::VARCHAR AS level,
    VALUE::VARCHAR AS message,
    RESOURCE_ATTRIBUTES['snow.database.name']::VARCHAR AS database_name,
    RESOURCE_ATTRIBUTES['snow.schema.name']::VARCHAR AS schema_name,
    RESOURCE_ATTRIBUTES['snow.executable.name']::VARCHAR AS app_name,
    RECORD_ATTRIBUTES['log.iostream']::VARCHAR AS stream
FROM <event_table>
WHERE RESOURCE_ATTRIBUTES['snow.database.name'] = '<database_name>'
  AND RESOURCE_ATTRIBUTES['snow.schema.name'] = '<schema_name>'
  AND RESOURCE_ATTRIBUTES['snow.executable.name'] = '<app_name>'
  AND RECORD_TYPE = 'LOG'
  AND TIMESTAMP > DATEADD(hour, -1, CURRENT_TIMESTAMP())
ORDER BY TIMESTAMP DESC
LIMIT 100;
Copy

Substitua <event_table> pelo nome da tabela de eventos retornado pelo comando SHOW PARAMETERS e substitua <database_name>, <schema_name> e <app_name> pelos valores do seu app Streamlit.

Dica

Inclua um filtro TIMESTAMP nas consultas da tabela de eventos para melhorar o desempenho. As tabelas de eventos podem conter um grande volume de dados de vários componentes do Snowflake.

Para obter mais informações sobre as colunas da tabela de eventos, consulte Colunas da tabela de eventos.

Registro em log do tempo de execução de warehouse

Para apps Streamlit que usam tempos de execução de warehouse, você pode capturar mensagens de log e rastrear eventos do código do seu app Streamlit enquanto ele é executado e, em seguida, analisar os resultados com SQL, por exemplo, para analisar erros. Para obter mais informações, consulte Registro, rastreamento e métricas.

Os tempos de execução de warehouse exigem que os níveis de log e rastreamento sejam definidos no banco de dados que contém seu app:

-- Set the log level for the database containing your app
ALTER DATABASE <database_name> SET LOG_LEVEL = INFO;

-- Set the trace level for the database containing your app
ALTER DATABASE <database_name> SET TRACE_LEVEL = ON_EVENT;
Copy

Exemplo: Registro de um app de tempo de execução de warehouse

import logging
import streamlit as st

logger = logging.getLogger("simple_logger")

# Write directly to the app
st.title("Simple Logging Example")

# Get the current credentials
session = st.connection('snowflake').session()

def get_log_messages_query() -> str:
    return """
            SELECT
                TIMESTAMP,
                RECORD:"severity_text"::VARCHAR AS SEVERITY,
                RESOURCE_ATTRIBUTES:"db.user"::VARCHAR AS USER,
                VALUE::VARCHAR AS VALUE
            FROM
                SAMPLE_EVENTS
            WHERE
                SCOPE:"name" = 'simple_logger'
            ORDER BY
                TIMESTAMP DESC;
            """

button = st.button("Log a message")

if button:
    try:
        logger.info("Logging an info message through Streamlit App.")
        st.success('Logged a message')
    except Exception as e:
        logger.error("Logging an error message through Streamlit App: %s",e)
        st.error('Logged an error')

sql = get_log_messages_query()

df = session.sql(sql).to_pandas()

with st.expander("**Show All Messages**"):
     st.dataframe(df, use_container_width=True)
Copy

Rastreamento (somente tempos de execução de warehouse)

O rastreamento é compatível apenas com tempos de execução de warehouse. Você pode emitir eventos de rastreamento do app Streamlit e consultar a tabela de eventos para analisá-los.

Nota

O exemplo a seguir requer a instalação do pacote snowflake-telemetry-python. Para obter mais informações, consulte Adição de suporte ao pacote de telemetria.

import streamlit as st
import time
import random
from snowflake import telemetry

def sleep_function() -> int:
    random_time = random.randint(1, 10)
    time.sleep(random_time)
    return random_time

def get_trace_messages_query() -> str:
    return """
            SELECT
                TIMESTAMP,
                RESOURCE_ATTRIBUTES :"db.user" :: VARCHAR AS USER,
                RECORD_TYPE,
                RECORD_ATTRIBUTES
            FROM
                SAMPLE_EVENTS
            WHERE
                RECORD :"name" :: VARCHAR = 'tracing_some_data'
                OR RECORD_ATTRIBUTES :"logging_demo.tracing" :: VARCHAR = 'begin_span'
            ORDER BY
                TIMESTAMP DESC;
            """

def trace_message() -> None:
    execution_time = sleep_function()
    telemetry.set_span_attribute("logging_demo.tracing", "begin_span")
    telemetry.add_event(
        "tracing_some_data",
        {"function_name": "sleep_function", "execution_time": execution_time},
    )

# Write directly to the app
st.title("Simple Tracing Example")

# Get the current credentials
session = st.connection('snowflake').session()

button = st.button("Add trace event")

if button:
    with st.spinner("Executing function..."):
        trace_message()
        st.toast("Successfully log a trace message!", icon="✅")

sql = get_trace_messages_query()

df = session.sql(sql).to_pandas()

with st.expander("**Show All Trace Messages**"):
     st.dataframe(df, use_container_width=True)
Copy