Python 檢測工具範例

本文說明如何修改 Python 應用程式,使用開放原始碼 OpenTelemetry 架構收集追蹤記錄和指標資料,以及如何將結構化 JSON 記錄寫入標準輸出。本文也提供可安裝及執行的 Python 應用程式範例相關資訊。這個應用程式使用 Flask 網頁架構,並已設定為產生指標、追蹤記錄和記錄檔。

如要進一步瞭解插樁,請參閱下列文件:

手動和零程式碼檢測簡介

對於這個語言,OpenTelemetry 將零程式碼檢測定義為從程式庫和架構收集遙測資料的做法,且無須變更程式碼。不過,您必須安裝模組並設定環境變數。

本文不會說明零程式碼的插碼作業。如要瞭解這個主題,請參閱「Python 零程式碼檢測」。

如需一般資訊,請參閱 OpenTelemetry Instrumentation for Python

事前準備

Enable the Cloud Logging, Cloud Monitoring, and Cloud Trace APIs.

Enable the APIs

檢測應用程式,收集追蹤記錄、指標和記錄檔

如要為應用程式進行檢測,以收集追蹤記錄和指標資料,並將結構化 JSON 寫入標準輸出,請按照本文後續章節所述步驟操作:

  1. 設定 OpenTelemetry
  2. 設定結構化記錄

設定 OpenTelemetry

這個範例應用程式已設定為使用 OpenTelemetry Python SDK,透過 OTLP 通訊協定匯出追蹤記錄和指標。根據預設,OpenTelemetry Python SDK 會使用 W3C 追蹤內容格式傳播追蹤內容,確保追蹤記錄中的範圍具有正確的父項/子項關係。

以下程式碼範例說明如何使用 Python 模組設定 OpenTelemetry。如要查看完整範例,請按一下「更多」圖示 ,然後選取「在 GitHub 上查看」

def setup_opentelemetry() -> None:
    resource = Resource.create(
        attributes={
            # Use the PID as the service.instance.id to avoid duplicate timeseries
            # from different Gunicorn worker processes.
            SERVICE_INSTANCE_ID: f"worker-{os.getpid()}",
        }
    )

    # Set up OpenTelemetry Python SDK
    tracer_provider = TracerProvider(resource=resource)
    tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
    trace.set_tracer_provider(tracer_provider)

    logger_provider = LoggerProvider(resource=resource)
    logger_provider.add_log_record_processor(BatchLogRecordProcessor(OTLPLogExporter()))
    logs.set_logger_provider(logger_provider)

    event_logger_provider = EventLoggerProvider(logger_provider)
    events.set_event_logger_provider(event_logger_provider)

    reader = PeriodicExportingMetricReader(OTLPMetricExporter())
    meter_provider = MeterProvider(metric_readers=[reader], resource=resource)
    metrics.set_meter_provider(meter_provider)

Flask 應用程式會依據 Flask「部署至正式環境」指南中的建議,透過 Gunicorn 處理 HTTP 要求。Gunicorn 會啟動多個應用程式副本,在獨立的工作站程序中執行,以提高總處理量。為確保工作站程序的指標不會彼此衝突,建議每個工作站程序為 service.instance.id 資源屬性設定唯一值。其中一種做法是在 service.instance.id 中加入程序 ID。詳情請參閱「時間序列衝突」。

如要瞭解詳情和設定選項,請參閱 OpenTelemetry Python 檢測

設定結構化記錄

如要編寫與追蹤記錄相關聯的結構化記錄,請將應用程式設定為輸出 JSON 格式的記錄至標準輸出,並使用包含追蹤記錄資訊的金鑰。下列程式碼範例說明如何設定標準 logging 程式庫,使用 python-json-logger 程式庫輸出 JSON 結構化記錄,以及如何使用 opentelemetry-instrumentation-logging 套件納入追蹤資訊。

class JsonFormatter(jsonlogger.JsonFormatter):
    def formatTime(self, record: logging.LogRecord, datefmt: Optional[str] = None):
        # Format the timestamp as RFC 3339 with microsecond precision
        isoformat = datetime.fromtimestamp(record.created).isoformat()
        return f"{isoformat}Z"


def setup_structured_logging() -> None:
    LoggingInstrumentor().instrument()

    log_handler = logging.StreamHandler()
    formatter = JsonFormatter(
        "%(asctime)s %(levelname)s %(message)s %(otelTraceID)s %(otelSpanID)s %(otelTraceSampled)s",
        rename_fields={
            "levelname": "severity",
            "asctime": "timestamp",
            "otelTraceID": "logging.googleapis.com/trace",
            "otelSpanID": "logging.googleapis.com/spanId",
            "otelTraceSampled": "logging.googleapis.com/trace_sampled",
        },
    )
    log_handler.setFormatter(formatter)
    logging.basicConfig(
        level=logging.INFO,
        handlers=[log_handler],
    )

先前的設定會從記錄訊息中擷取有效跨度相關資訊,然後將該資訊做為屬性新增至 JSON 結構化記錄。這些屬性可用於將記錄與追蹤記錄建立關聯:

  • logging.googleapis.com/trace:與記錄項目相關聯的追蹤記錄資源名稱。
  • logging.googleapis.com/spanId:與記錄項目相關聯的追蹤記錄時距 ID。
  • logging.googleapis.com/trace_sampled:這個欄位的值必須是 truefalse

如要進一步瞭解這些欄位,請參閱 LogEntry 結構。

執行設定為收集遙測資料的範例應用程式

範例應用程式使用與供應商無關的格式,包括記錄的 JSON 格式,以及指標和追蹤記錄的 OTLP 格式。應用程式的遙測資料會透過 OpenTelemetry Collector (已設定 Google 匯出工具) 傳送至 Google Cloud 。這個檔案使用 Flask 處理 HTTP 要求,並使用 requests 程式庫發出 HTTP 要求。如要為 HTTP 用戶端和伺服器產生指標和追蹤記錄,範例應用程式會安裝 opentelemetry-instrumentation-flaskopentelemetry-instrumentation-requests 檢測程式庫:

logger = logging.getLogger(__name__)

# Initialize OpenTelemetry Python SDK and structured logging
setup_opentelemetry()
setup_structured_logging()

app = Flask(__name__)

# Add instrumentation
FlaskInstrumentor().instrument_app(app)
RequestsInstrumentor().instrument()

這個應用程式有兩個端點:

  • /multi 端點是由 multi 函式處理。應用程式中的負載產生器會向 /multi 端點發出要求。這個端點收到要求時,會向本機伺服器上的 /single 端點傳送三到七個要求。

    @app.route("/multi")
    def multi():
        """Handle an http request by making 3-7 http requests to the /single endpoint."""
        sub_requests = randint(3, 7)
        logger.info("handle /multi request", extra={"subRequests": sub_requests})
        for _ in range(sub_requests):
            requests.get(url_for("single", _external=True))
        return "ok"
    
    
  • /single 端點是由 single 函式處理。這個端點收到要求時,會短暫休眠,然後以字串回應。

    @app.route("/single")
    def single():
        """Handle an http request by sleeping for 100-200 ms, and write the number of seconds slept as the response."""
        duration = uniform(0.1, 0.2)
        logger.info("handle /single request", extra={"duration": duration})
        time.sleep(duration)
        return f"slept {duration} seconds"
    
    

下載及部署應用程式

如要執行範例,請按照下列步驟操作:

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 複製存放區:

    git clone https://github.com/GoogleCloudPlatform/opentelemetry-operations-python
    
  3. 前往範例目錄:

    cd opentelemetry-operations-python/samples/instrumentation-quickstart
    
  4. 建構並執行範例:

    docker compose up --abort-on-container-exit
    

    如果不是在 Cloud Shell 上執行,請執行應用程式,並讓 GOOGLE_APPLICATION_CREDENTIALS 環境變數指向憑證檔案。應用程式預設憑證會在 $HOME/.config/gcloud/application_default_credentials.json 提供憑證檔案。

    # Set environment variables
    export GOOGLE_CLOUD_PROJECT="PROJECT_ID"
    export GOOGLE_APPLICATION_CREDENTIALS="$HOME/.config/gcloud/application_default_credentials.json"
    export USERID="$(id -u)"
    
    # Run
    docker compose -f docker-compose.yaml -f docker-compose.creds.yaml up --abort-on-container-exit
    

查看指標

範例應用程式中的 OpenTelemetry 檢測會產生 Prometheus 指標,您可以使用 Metrics Explorer 查看這些指標:

  • Prometheus/http_server_duration_milliseconds/histogram 記錄伺服器要求的持續時間,並將結果儲存在直方圖中。

  • Prometheus/http_client_duration_milliseconds/histogram 記錄用戶端要求的時間長度,並將結果儲存在直方圖中。

如要查看範例應用程式產生的指標,請按照下列步驟操作:
  1. 前往 Google Cloud 控制台的 「Metrics Explorer」頁面:

    前往 Metrics Explorer

    如果您是使用搜尋列尋找這個頁面,請選取子標題為「Monitoring」的結果

  2. 在 Google Cloud 控制台的工具列中,選取您的 Google Cloud 專案。 如要進行 App Hub 設定,請選取 App Hub 主專案或已啟用應用程式的資料夾的管理專案。
  3. 在「指標」元素中,展開「選取指標」選單, 在篩選列中輸入 http_server, 然後使用子選單選取特定資源類型和指標:
    1. 在「Active resources」(有效資源) 選單中,選取「Prometheus Target」(Prometheus 目標)
    2. 在「Active metric categories」(使用中的指標類別) 選單中,選取「Http」
    3. 在「Active metrics」(使用中的指標) 選單中,選取指標。
    4. 按一下 [套用]
  4. 設定資料的顯示方式。

    如果指標的測量值是累計值,指標探索工具會自動以對齊週期將測量資料正規化,因此圖表會顯示比率。詳情請參閱「種類、型別和轉換」。

    測量整數或雙精度值時 (例如使用兩個 counter 指標),Metrics Explorer 會自動加總所有時間序列。如要查看 /multi/single HTTP 路由的資料,請將「Aggregation」(彙整) 項目中的第一個選單設為「None」(無)

    如要進一步瞭解如何設定圖表,請參閱「使用 Metrics Explorer 時選取指標」。

查看追蹤記錄

追蹤資料可能需要幾分鐘才會顯示。舉例來說,當專案收到追蹤記錄資料時,Google Cloud Observability 可能需要建立資料庫來儲存該資料。建立資料庫可能需要幾分鐘,這段期間無法查看任何追蹤資料。

如要查看追蹤記錄資料,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台的「Trace Explorer」頁面:

    前往「Trace Explorer」頁面

    您也可以透過搜尋列找到這個頁面。

  2. 在頁面的表格部分,選取跨度名稱為 /multi 的資料列。
  3. 在「Trace details」(追蹤記錄詳細資料) 面板的甘特圖中,選取標示為 /multi 的時距。

    畫面上會開啟一個面板,顯示 HTTP 要求相關資訊。這些詳細資料包括方法、狀態碼、位元組數,以及呼叫者的使用者代理程式。

  4. 如要查看與這項追蹤記錄相關聯的記錄檔,請選取「記錄檔和事件」分頁標籤。

    這個分頁會顯示個別記錄。如要查看記錄項目的詳細資料,請展開記錄項目。您也可以按一下「查看記錄」,然後使用記錄探索工具查看記錄。

如要進一步瞭解如何使用 Cloud Trace 探索工具,請參閱「尋找及探索追蹤記錄」。

查看記錄檔

您可以在記錄檔探索器中檢查記錄,也可以查看相關聯的追蹤記錄 (如有)。

  1. 前往 Google Cloud 控制台的「Logs Explorer」頁面:

    前往「Logs Explorer」(記錄檔探索工具)

    如果您是使用搜尋列尋找這個頁面,請選取子標題為「Logging」的結果

  2. 找出說明為 handle /multi request 的記錄。

    如要查看記錄詳細資料,請展開記錄項目。

  3. 在含有「handle /multi request」訊息的記錄項目上,按一下 「追蹤記錄」,然後選取「查看追蹤記錄詳細資料」

    「Trace details」(追蹤記錄詳細資料) 面板隨即開啟,並顯示所選追蹤記錄。

    記錄資料可能比追蹤資料早幾分鐘提供。如果透過 ID 搜尋追蹤記錄或按照這項工作中的步驟查看追蹤記錄資料時發生錯誤,請稍候一到兩分鐘,然後重試。

如要進一步瞭解如何使用記錄檔探索工具,請參閱「使用記錄檔探索工具查看記錄檔」。

後續步驟