Streamlit in Snowflake 用のログおよびトレース¶
|sis|は、ウェアハウスとコンテナランタイムの両方のログ記録をサポートしています。ウェアハウスランタイムは、Snowflakeテレメトリフレームワークを使用してログメッセージをキャプチャし、イベントをトレースしてイベントテーブルに記録します。コンテナランタイムは、アプリが標準出力と標準エラーに出力するログをキャプチャし、アカウントのイベントテーブルに保存します。また、|sf-web-interface|のライブコンソールログと履歴ログビューの両方を提供します。
どちらのランタイムもアカウントレベルのイベントテーブルにログを保存します。ログをキャプチャするには、アカウント管理者がこのイベントテーブルを設定し、構成する必要があります。手順については、 イベントテーブルの概要 をご参照ください。
アカウント用に構成されたイベントテーブルを見つけるには、次を実行します。
SHOW PARAMETERS LIKE 'event_table' IN ACCOUNT;
次のテーブルは、ランタイム別にログ記録とトレースのサポートを比較したものです。
機能 |
ウェアハウスランタイム |
コンテナランタイム(プレビュー) |
|---|---|---|
イベントテーブルのログ |
サポート対象 |
サポート対象 |
トレース |
サポート対象 |
サポート対象外 |
|sf-web-interface|のライブコンソールログ |
サポート対象外 |
サポート対象 |
|sf-web-interface|の履歴ログ |
サポート対象外 |
サポート対象 |
コンテナランタイムのログ¶
コンテナランタイムのStreamlitアプリは|SPCS|コンテナ内で実行されます。Snowflakeは、アプリが標準出力と標準エラーに出力するものを自動的にキャプチャし、アカウントのイベントテーブルに格納します。これらのログは|sf-web-interface|で表示したりSQLでクエリしたりできます。
Pythonのログ記録モジュール¶
Pythonの組み込み``logging``モジュールを使用して、アプリからログメッセージを出力します。次の例では、INFOレベル以上のメッセージを標準出力に書き込むロガーを構成しています。
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")
重大度が低いものから高いものの順に、Pythonには以下のログレベルがあります。
DEBUG
INFO
WARNING
ERROR
レベルをINFOに設定すると、INFO、WARNING、ERRORメッセージがキャプチャされますが、DEBUGメッセージはキャプチャされません。
注釈
デフォルトでは、Pythonの``logging``モジュールは標準エラー(sys.stderr)に書き込みます。Snowflakeは標準出力と標準エラーの両方をキャプチャするため、使用するストリームに関係なくログがキャプチャされます。ただし、標準エラーは慣例的にエラー出力用に予約されているため、ストリームを``sys.stdout``に設定することがオプションとして推奨されます。
ロガーを構成したら、アプリコード全体でメッセージをログに記録するために使用できます。ロガーは別のモジュールで定義し、アプリコードにインポートするのが一般的です。
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)
|sf-web-interface|のライブログ¶
|sf-web-interface|でコンテナランタイムアプリを編集する場合、エディターの下にログペインが表示されます。このペインには、アプリがログメッセージを出力すると、リアルタイムでログメッセージがストリーミングされます。最初に接続したときに、最新のログの簡単な履歴が表示されます。
各ログエントリは、次の情報を示します。
列 |
説明 |
|---|---|
|
``APP``(Streamlitプロセスおよびユーザー構成のロガーからのログ)または``MANAGER``(コンテナを管理するシステムプロセスからのログ)。 |
|
ログメッセージの重大度レベル(DEBUG、INFO、WARNING、ERROR)。 |
|
ログメッセージのコンテンツ。 |
利用可能なライブログアクション¶
ログペインの右上隅で、ログを検索およびフィルターして、必要な情報を見つけることができます。これには、テキスト検索、ソースによるフィルタリング、重大度レベルによるフィルタリングが含まれます。3つのドットメニューで、現在のログをダウンロードしたり、過去のログに移動したり、ライブログペインをクリアしたりできます。ペインをクリアすると、現在のログは現在のビューから削除されますが、イベントテーブルからは削除されません。ページをすぐにリロードすると、最新のログが復元されます。
ログソースの理解¶
コンテナランタイムアプリからのログには、2つのソースのいずれかがあります。
MANAGER:アプリを準備して実行するコンテナ内のシステムプロセス。マネージャーログには、ステージからのアプリファイルのダウンロード、Python依存関係のインストール、Streamlitサーバープロセスの開始に関するメッセージが含まれます。アプリの実行中にアプリの依存関係ファイルを更新すると、マネージャープロセスは依存関係を再インストールし、追加のマネージャーログを生成します。APP:実行中のStreamlitサーバープロセスからのログ。これには、ユーザー設定のPythonロガー、Streamlitの組み込みロガーからのメッセージ、およびアプリが標準出力や標準エラーに書き込むその他の出力が含まれます。
ソース間の境界は``streamlit run``コマンドです。Streamlitプロセスを開始する前にコンテナが行うすべてのタスクは、``MANAGER``ログを生成します。Streamlitプロセスが開始されると、そのプロセスからの出力は``APP``ログを生成します。
|sf-web-interface|での履歴ログの表示¶
次のステップは、コンテナランタイムアプリにのみ適用されます。ウェアハウスランタイムアプリにはログペインがありません。
Snowsight にサインインします。
ナビゲーションメニューで、 Projects » Streamlit を選択してから、アプリを選択します。
ページの右上隅で、 Edit を選択します。
ログペインの右上隅で、3つのドットメニュー(Other actions)|raa| :ui:`Historical logs`を選択します。
これにより、アプリの背後で実行されているサービスの|SPCS|モニタリングページが開きます。ログテーブルには、次の列が表示されます。
列 |
説明 |
|---|---|
タイムスタンプ |
ログメッセージのタイムスタンプ。 |
インスタンス ID |
コンテナインスタンスの識別子。Streamlitアプリではこれは常に``0``になります。 |
コンテナー |
コンテナインスタンスの識別子。 |
ストリーム |
ログが標準出力( |
値 |
|
モニタリングページの詳細については、:doc:`/developer-guide/snowpark-container-services/monitoring-services`をご参照ください。
SQLでのログのクエリ¶
イベントテーブルを直接クエリして、コンテナランタイムアプリのログを分析できます。以下のクエリは、特定のStreamlitアプリからログを取得します。
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;
<event_table>``をSHOW PARAMETERSコマンドで返されたイベントテーブル名に置き換え、``<database_name>、<schema_name>、``<app_name>``をStreamlitアプリの値に置き換えます。
Tip
パフォーマンスを向上させるには、イベントテーブルのクエリにTIMESTAMPフィルターを含めます。イベントテーブルには、さまざまなSnowflakeコンポーネントからの大量のデータが含まれる場合があります。
イベントテーブル列の詳細については、:doc:`/developer-guide/logging-tracing/event-table-columns`をご参照ください。
ウェアハウスランタイムのログ記録¶
ウェアハウスランタイムを使用するStreamlitアプリの場合、Streamlitアプリコードの実行時にログメッセージやトレースイベントをキャプチャし、その結果をSQLで分析することで、例えばエラーを分析することができます。詳細については、 ロギング、トレース、メトリクス をご参照ください。
ウェアハウスのランタイムでは、アプリを含むデータベースにログとトレースのレベルを設定する必要があります。
-- 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;
例:ウェアハウスランタイムアプリからのログ記録¶
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)
トレース(ウェアハウスランタイムのみ)¶
トレースはウェアハウスランタイムでのみサポートされています。Streamlitアプリからトレースイベントを発行し、イベントテーブルをクエリして分析することができます。
注釈
以下の例では、 snowflake-telemetry-python パッケージをインストールする必要があります。詳細については、 テレメトリパッケージのサポートの追加 をご参照ください。
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)