實作 X-Ray 追蹤

AWS 監控與疑難排解

John Q. Martin

Principal Consultant

X-Ray SDK 概觀

 

重點資訊:

  • 支援語言:Python、Node.js、Java、.NET、Go、Ruby
  • 兩種方式:自動與手動插裝
  • SDK 透過 UDP 連接埠 2000 與 daemon 溝通
  • 絕不直接呼叫 X-Ray API

 

自動 vs 手動:

自動與手動 X-Ray SDK 插裝方式的比較

AWS 監控與疑難排解

Python SDK:Flask 設定

 

from flask import Flask
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.ext.flask.middleware import XRayMiddleware

app = Flask(__name__)

xray_recorder.configure(
    service='MyFlaskApp',
    sampling=True,
    context_missing='LOG_ERROR',
    daemon_address='127.0.0.1:2000'
)

XRayMiddleware(app, xray_recorder)

 

四個 recorder 設定:

  • service-在服務地圖中顯示的名稱
  • sampling-開啟/關閉取樣
  • context_missingLOG_ERROR 可避免程式當掉
  • daemon_address-片段傳送目的地

掛上 middleware 後,所有進站請求都會自動追蹤。

AWS 監控與疑難排解

自動插裝:Python

 

# 插裝所有支援的函式庫
from aws_xray_sdk.core import patch_all
patch_all()
# 或選擇性插裝
from aws_xray_sdk.core import patch
patch(['boto3', 'requests', 'psycopg2'])

 

支援的函式庫:

X-Ray 自動插裝支援的函式庫,如 boto3、requests 與資料庫用戶端

AWS 監控與疑難排解

手動插裝:Python

 

Decorator 作法:

@xray_recorder.capture('process_order')
def process_order(order_id):
    order = get_order(order_id)
    return process_payment(order)

 

內容管理器作法:

def process_order(order_id):
    with xray_recorder.capture('fetch_order'):
        order = db.query(Order).filter_by(
            id=order_id).first()
    with xray_recorder.capture('process_payment'):
        return payment_service.charge(order.total)
AWS 監控與疑難排解

程式中的註解與中繼資料

 

加入註解(annotation):

xray_recorder.put_annotation(
    'order_id', order_id)
xray_recorder.put_annotation(
    'user_id', user_id)

 

加入中繼資料(metadata,詳細情境):

xray_recorder.put_metadata(
    'order_details',
    {'items': order.items,
     'total': order.total})
  • 註解會建立索引;中繼資料不會
  • 註解有型別;中繼資料可為任意 JSON
  • 用註解做篩選;用中繼資料帶除錯脈絡
AWS 監控與疑難排解

追蹤中的錯誤處理

 

def process_order(order_id):
    try:
        order = get_order(order_id)
        payment = process_payment(order)
        return payment
    except PaymentError as e:
        xray_recorder.put_annotation(
            'error_type', 'payment_failed')
        xray_recorder.put_metadata(
            'error_details',
            {'message': str(e), 'order_id': order_id})
        raise

 

  • 追蹤到的函式內拋出的例外會「自動擷取」
  • 加上錯誤類型的註解,方便在主控台篩選
  • 加上中繼資料以保存完整錯誤細節
  • 記得重新拋出;你的應用程式錯誤處理仍需執行
AWS 監控與疑難排解

Node.js SDK:Express 設定

 

const AWSXRay = require('aws-xray-sdk-core');
const xrayExpress = require('aws-xray-sdk-express');
const app = require('express')();

AWSXRay.config([AWSXRay.plugins.EC2Plugin]);

// 為所有進站請求開啟 segment
app.use(xrayExpress.openSegment('MyExpressApp'));

app.get('/api/orders/:id', async (req, res) => {
    const order = await fetchOrder(req.params.id);
    res.json({ order });
});

// 回應後關閉 segment
app.use(xrayExpress.closeSegment());

// 自動插裝
const AWS = AWSXRay.captureAWS(require('aws-sdk'));
const https = AWSXRay.captureHTTPs(require('https'));
AWS 監控與疑難排解

Lambda 實作

 

from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all

patch_all()  # 插裝 AWS SDK 呼叫

def lambda_handler(event, context):
    xray_recorder.put_annotation(
        'user_id', event['user_id'])

    result = process_user(event['user_id'])

    return {
        'statusCode': 200,
        'body': json.dumps(result)
    }

 

重點資訊:

  • 啟用 Active Tracing 時,Lambda 會自動送出基本追蹤;此功能不需 SDK
  • 安裝 X-Ray SDK 可加入子片段、註解,並插裝下游呼叫
  • 在主控台啟用:Configuration → Monitoring tools
  • 或在樣板設定:Tracing: Active
AWS 監控與疑難排解

ECS 與 Fargate:sidecar 模式

 

工作結構:

ECS Task
|_ Application Container
|   sends to xray-daemon:2000
|_ X-Ray Daemon Container
    forwards to X-Ray service

應用容器設定:

xray_recorder.configure(
    service='MyECSApp',
    daemon_address='xray-daemon:2000'
)

 

工作定義需包含:

  • Daemon 容器amazon/aws-xray-daemon 映像,UDP 連接埠 2000
  • App 容器:環境變數 AWS_XRAY_DAEMON_ADDRESS=xray-daemon:2000

為何用 sidecar?

  • Daemon 隨任務擴縮
  • 失敗侷限於各任務,彼此隔離
AWS 監控與疑難排解

安裝 X-Ray daemon

依平台安裝:

  • Amazon Linux 2
    • sudo yum install -y aws-xray-daemon-3.x.rpm
  • Ubuntu
    • sudo dpkg -i aws-xray-daemon-3.x.deb
  • Windows
    • xray.exe -f cfg.yaml install
  • Docker
    • docker run -p 2000:2000/udp amazon/aws-xray-daemon

安裝後:

sudo systemctl start xray
sudo systemctl enable xray

daemon 的工作:

  • 監聽 UDP 連接埠 2000
  • 緩衝並批次傳送片段
  • 透過 HTTPS 轉送到 X-Ray API
  • 處理重試;你的應用不需負責
AWS 監控與疑難排解

daemon 設定

 

TotalBufferSizeMB: 24
Concurrency: 8
Region: "us-east-1"
Socket:
  UDPAddress: "127.0.0.1:2000"
  TCPAddress: "127.0.0.1:2000"
Logging:
  LogLevel: "info"
  LogPath: "/var/log/xray/xray-daemon.log"
LocalMode: false

 

  • 緩衝大小;高流量時可加大
  • Concurrency 設定與 X-Ray 的平行連線數
  • 容器環境請將 UDP 位址設為 0.0.0.0
  • 本機模式:本機開發無憑證時設為 true
AWS 監控與疑難排解

IAM 權限

 

{
  "Effect": "Allow",
  "Action": [
    "xray:PutTraceSegments",
    "xray:PutTelemetryRecords",
    "xray:GetSamplingRules",
    "xray:GetSamplingTargets",
    "xray:GetSamplingStatisticSummaries"
  ],
  "Resource": "*"
}

 

最簡作法

使用受管原則 AWSXRayDaemonWriteAccess

套用到:

  • EC2 執行個體角色
  • ECS 工作角色
  • Lambda 執行角色

沒有正確權限時,daemon 會執行但無聲失敗,無法送出片段。

AWS 監控與疑難排解

daemon 部署模式

 

三種 X-Ray daemon 部署模式:每台機器、sidecar、共用服務

AWS 監控與疑難排解

課程總結

 

  • SDKpatch_all() 自動插裝;decorator 與內容管理器為手動插裝
  • 註解(可索引、可搜尋)vs 中繼資料(詳細、不建索引)
  • Lambda:自動送出基本追蹤;安裝 SDK 可加子片段與下游呼叫
  • ECS/Fargate:採 sidecar daemon 容器模式
  • daemon:由 cfg.yaml 設定,需 AWSXRayDaemonWriteAccess IAM 原則
  • 部署:EC2 用每台機器;容器用 sidecar
AWS 監控與疑難排解

實作 X-Ray 追蹤

AWS 監控與疑難排解

Preparing Video For Download...