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;
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")
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
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)
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 |
|---|---|
|
|
|
O nível de gravidade da mensagem de log (DEBUG, INFO, WARNING, ERROR). |
|
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.
Faça login no Snowsight.
No menu de navegação, clique em Projects » Streamlit e selecione seu app.
No canto superior direito da página, selecione Edit.
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 |
Contêiner |
O identificador da instância de contêiner. |
Fluxo |
Se o log foi emitido para saída padrão ( |
Valor |
A mensagem de log com formatação JSON que inclui os campos |
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;
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;
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)
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)