Streamlit in Snowflake 에 대한 로깅 및 추적¶
Streamlit in Snowflake 는 Warehouse Runtime 및 Container Runtime 모두에 대한 로깅을 지원합니다. Warehouse Runtime은 Snowflake 원격 분석 프레임워크를 사용하여 로그 메시지를 캡처하고 이벤트를 이벤트 테이블로 추적합니다. Container Runtime은 앱이 표준 출력 및 표준 오류로 내보내는 로그를 캡처하여 계정의 이벤트 테이블에 저장하고 Snowsight 에서 라이브 콘솔 로그와 기록 로그 뷰를 모두 제공합니다.
두 런타임 모두 계정 수준 이벤트 테이블에 로그를 저장합니다. 로그를 캡처하려면 먼저 계정 관리자가 이 이벤트 테이블을 설정하고 구성해야 합니다. 자세한 지침은 이벤트 테이블 개요 섹션을 참조하십시오.
계정에 대해 구성된 이벤트 테이블을 찾으려면 다음을 실행합니다.
SHOW PARAMETERS LIKE 'event_table' IN ACCOUNT;
다음 테이블에서는 런타임별 로깅 및 추적 지원을 비교합니다.
특징 |
Warehouse Runtime |
Container Runtime(미리 보기) |
|---|---|---|
이벤트 테이블 로깅 |
지원됨 |
지원됨 |
추적 |
지원됨 |
지원되지 않음 |
Snowsight 의 라이브 콘솔 로그 |
지원되지 않음 |
지원됨 |
Snowsight 의 기록 로그 |
지원되지 않음 |
지원됨 |
Container Runtime 로깅¶
Container Runtime Streamlit 앱은 Snowpark Container Services 컨테이너 내부에서 실행됩니다. Snowflake는 앱이 표준 출력 및 표준 오류로 내보내는 모든 로그를 자동으로 캡처하여 계정의 이벤트 테이블에 저장합니다. 이러한 로그는 Snowsight 에서 확인하거나 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)
Snowsight 의 라이브 로그인¶
Snowsight 에서 Container Runtime 앱을 편집할 때 편집기 아래에 로그 창이 나타납니다. 이 창은 앱에서 로그 메시지를 내보낼 때 실시간으로 로그 메시지를 스트리밍합니다. 처음 연결할 때 가장 최근 로그의 짧은 기록이 표시됩니다.
각 로그 항목에는 다음 정보가 표시됩니다.
열 |
설명 |
|---|---|
|
Streamlit 프로세스의 로그 및 사용자 구성 로그의 경우 ``APP``이거나 컨테이너를 관리하는 시스템 프로세스의 로그의 경우 ``MANAGER``입니다. |
|
로그의 심각도 수준(DEBUG, INFO, WARNING, ERROR)입니다. |
|
로그 메시지 내용입니다. |
사용 가능한 라이브 로그 작업¶
로그 창의 오른쪽 상단에서 로그를 검색하고 필터링하여 필요한 정보를 찾는 데 도움이 될 수 있습니다. 여기에는 텍스트 검색, 소스별 필터링, 심각도 수준별 필터링이 포함됩니다. 점 3개 메뉴에서 현재 로그를 다운로드하거나 과거 로그로 이동하거나 라이브 로깅 창을 지울 수 있습니다. 창을 지우면 현재 로그가 현재 뷰에서 삭제되지만 이벤트 테이블에서는 삭제되지 않습니다. 페이지를 즉시 다시 로드하면 가장 최근 로그가 복원됩니다.
로그 소스 이해하기¶
Container Runtime 앱의 로그에는 다음 두 소스 중 하나가 있습니다.
MANAGER: 앱을 준비하고 실행하는 컨테이너 내부의 시스템 프로세스입니다. 관리자 로그에는 스테이지에서 앱 파일 다운로드, Python 종속 항목 설치, Streamlit 서버 프로세스 시작에 대한 메시지가 포함됩니다. 앱이 실행되는 동안 앱의 종속성 파일을 업데이트하면 관리자 프로세스가 종속성을 다시 설치하고 추가 관리자 로그를 생성합니다.APP: 실행 중인 Streamlit 서버 프로세스의 로그입니다. 여기에는 사용자 구성 Python 로거, Streamlit의 기본 제공 로거, 앱이 표준 출력 또는 표준 오류에 작성하는 기타 모든 출력의 메시지가 포함됩니다.
소스 간의 경계는 streamlit run 명령입니다. Streamlit 프로세스를 시작하기 전에 컨테이너가 수행하는 모든 작업은 MANAGER 로그를 생성합니다. Streamlit 프로세스가 시작된 후 해당 프로세스의 출력은 APP 로그를 생성합니다.
Snowsight 에서 과거 로그 보기¶
다음 단계는 Container Runtime 앱에만 적용됩니다. Warehouse Runtime 앱에는 로그 창이 없습니다.
Snowsight 에 로그인합니다.
탐색 메뉴에서 Projects » :ui:`Streamlit`을 선택한 후 앱을 선택합니다.
페이지의 오른쪽 위 모서리에서 Edit 를 선택합니다.
로그 창의 오른쪽 상단에서 점 3개 메뉴(Other actions) » :ui:`Historical logs`를 선택합니다.
그러면 앱 뒤에서 실행되는 서비스에 대한 Snowpark Container Services 모니터링 페이지가 열립니다. 로그 테이블에는 다음 열이 표시됩니다.
열 |
설명 |
|---|---|
타임스탬프 |
로그 메시지의 타임스탬프입니다. |
인스턴스 ID |
컨테이너 인스턴스의 식별자입니다. Streamlit 앱의 경우 이는 항상 ``0``입니다. |
컨테이너 |
컨테이너 인스턴스의 식별자입니다. |
스트림 |
로그가 표준 출력( |
값 |
|
모니터링 페이지에 대한 자세한 내용은 Snowpark Container Services: 모니터링 서비스 섹션을 참조하세요.
SQL을 사용한 쿼리 로그¶
이벤트 테이블을 직접 쿼리하여 Container Runtime 앱의 로그를 분석할 수 있습니다. 다음 쿼리는 특정 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 앱의 값으로 바꿉니다.
팁
이벤트 테이블 쿼리에 TIMESTAMP 필터를 포함하여 성능을 개선합니다. 이벤트 테이블에는 다양한 Snowflake 구성 요소의 대량 데이터가 포함될 수 있습니다.
이벤트 테이블 열에 대한 자세한 내용은 이벤트 테이블 열 섹션을 참조하세요.
Warehouse Runtime 로깅¶
예를 들어, Warehouse Runtime을 사용하는 Streamlit 앱의 경우 Streamlit 앱 코드가 실행될 때 로그 메시지를 캡처하고 이벤트를 추적한 다음 SQL로 결과를 분석하여 오류를 분석할 수 있습니다. 자세한 내용은 로깅, 추적 및 메트릭 섹션을 참조하십시오.
Warehouse Runtime을 사용하려면 앱이 포함된 데이터베이스에 로그 및 추적 수준을 설정해야 합니다.
-- 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;
예: Warehouse Runtime 앱에서 로깅하기¶
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)
추적(Warehouse Runtime만 해당)¶
추적은 Warehouse Runtime에만 지원됩니다. 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)