建AI大模型服務(wù)監(jiān)控系統(tǒng)實(shí)戰(zhàn))
在業(yè)務(wù)中大規(guī)模集成 AI 大模型時你是否遇到過這樣的困境用戶反饋響應(yīng)慢但后臺日志卻一切正常月度賬單上的 Token 消耗遠(yuǎn)超預(yù)期卻找不到具體是哪個接口或哪個用戶消耗的傳統(tǒng)的應(yīng)用性能監(jiān)控APM工具對 AI 調(diào)用的延遲、Token 消耗等關(guān)鍵指標(biāo)往往無能為力導(dǎo)致成本失控和體驗(yàn)下降成為“黑盒”。本文將為你拆解一套完整的 AI 服務(wù)監(jiān)控解決方案。我們將聚焦于兩個核心可觀測性指標(biāo)響應(yīng)延遲與Token 消耗并使用OpenTelemetry進(jìn)行指標(biāo)采集最終將數(shù)據(jù)存儲和展示在ClickHouse中。通過本篇實(shí)戰(zhàn)指南你將能搭建一個從數(shù)據(jù)采集、存儲到可視化分析的完整監(jiān)控鏈路無論是評估模型性能、優(yōu)化提示詞工程還是進(jìn)行精細(xì)化的成本核算都能做到心中有數(shù)。1. 核心概念為什么需要專門的 AI 監(jiān)控在深入技術(shù)實(shí)現(xiàn)之前我們首先要理解監(jiān)控 AI 服務(wù)與傳統(tǒng) Web 服務(wù)的本質(zhì)區(qū)別。1.1 AI 服務(wù)的獨(dú)特挑戰(zhàn)傳統(tǒng)的 Web 服務(wù)監(jiān)控主要關(guān)注請求 QPS、錯誤率、CPU/內(nèi)存使用率、數(shù)據(jù)庫查詢耗時等。而一次 AI 模型調(diào)用例如調(diào)用 OpenAI GPT-4 或本地部署的 Llama其核心成本與性能體現(xiàn)在Token 消耗這是 AI 服務(wù)最直接的成本驅(qū)動因素。無論是輸入Prompt還是輸出Completion都按 Token 數(shù)量計費(fèi)。監(jiān)控每個請求的輸入/輸出 Token 數(shù)是進(jìn)行成本分?jǐn)偂⒆R別異常消耗如提示詞泄露導(dǎo)致長輸出、優(yōu)化提示詞效率的基礎(chǔ)。響應(yīng)延遲AI 模型的推理時間通常遠(yuǎn)長于簡單的數(shù)據(jù)庫查詢。延遲包括網(wǎng)絡(luò)傳輸、模型加載、推理計算等多個環(huán)節(jié)。監(jiān)控 P50、P95、P99 分位的延遲對于保障用戶體驗(yàn)、設(shè)定合理的超時時間、評估不同模型或硬件的性能至關(guān)重要。模型與參數(shù)同一個服務(wù)可能調(diào)用不同的模型如gpt-3.5-turbo與gpt-4或使用不同的參數(shù)如temperature,max_tokens。監(jiān)控時需要區(qū)分這些維度才能進(jìn)行有效的對比分析。1.2 監(jiān)控架構(gòu)概覽我們的目標(biāo)是構(gòu)建一個輕量、高效、可擴(kuò)展的監(jiān)控系統(tǒng)。整體架構(gòu)如下[你的AI應(yīng)用] --(發(fā)射指標(biāo))-- [OpenTelemetry Collector] --(寫入)-- [ClickHouse] --(查詢)-- [Grafana]數(shù)據(jù)采集層 (OpenTelemetry SDK)集成到你的 AI 應(yīng)用代碼中在每次調(diào)用 AI 模型時記錄耗時、Token 數(shù)等指標(biāo)。收集與轉(zhuǎn)發(fā)層 (OpenTelemetry Collector)接收來自多個應(yīng)用實(shí)例的指標(biāo)數(shù)據(jù)進(jìn)行聚合、批處理并導(dǎo)出到指定的存儲后端。數(shù)據(jù)存儲層 (ClickHouse)一個高性能的列式數(shù)據(jù)庫特別適合存儲和快速查詢時序指標(biāo)數(shù)據(jù)。可視化層 (Grafana)從 ClickHouse 中讀取數(shù)據(jù)繪制豐富的監(jiān)控儀表盤。接下來我們將從環(huán)境準(zhǔn)備開始一步步實(shí)現(xiàn)這個架構(gòu)。2. 環(huán)境準(zhǔn)備與版本說明在開始動手之前請確保你的開發(fā)環(huán)境滿足以下要求。本文示例將使用 Python 作為 AI 應(yīng)用的語言但 OpenTelemetry 的概念是語言無關(guān)的。2.1 基礎(chǔ)軟件環(huán)境操作系統(tǒng)Linux (Ubuntu 20.04/22.04)、macOS 或 WSL2。大部分命令在 Linux 環(huán)境下進(jìn)行。Docker Docker Compose我們將使用容器化方式快速部署 OpenTelemetry Collector 和 ClickHouse。請確保已安裝。# 檢查安裝 docker --version docker-compose --versionPython版本 3.8 及以上。我們將使用openai庫模擬 AI 調(diào)用。python3 --version pip3 --version2.2 核心組件版本為了確保兼容性以下是本文演示所用的主要組件版本。你的實(shí)際環(huán)境可以略有不同但建議保持大版本一致。組件版本說明OpenTelemetry Python SDK1.24.0用于在應(yīng)用中埋點(diǎn)OpenTelemetry Collector0.104.0(Docker 鏡像)指標(biāo)收集與導(dǎo)出ClickHouse24.8.2-alpine(Docker 鏡像)指標(biāo)存儲Grafana11.2.0(Docker 鏡像)數(shù)據(jù)可視化OpenAI Python Client1.30.1模擬 AI 調(diào)用重要提示OpenTelemetry 生態(tài)系統(tǒng)更新較快配置方式可能隨版本變化。本文的代碼和配置基于上述版本測試通過如果你的版本不同請參考官方文檔進(jìn)行調(diào)整。3. OpenTelemetry 與 ClickHouse 基礎(chǔ)3.1 OpenTelemetry 簡介OpenTelemetry (簡稱 OTel) 是一個云原生計算基金會 (CNCF) 下的項(xiàng)目旨在提供一套統(tǒng)一的 API、SDK 和工具用于采集、生成遙測數(shù)據(jù)包括指標(biāo)、鏈路追蹤和日志。它的核心優(yōu)勢在于標(biāo)準(zhǔn)化和供應(yīng)商中立。對于 AI 監(jiān)控場景我們主要使用其Metrics SDK。一個Meter工具可以創(chuàng)建各種指標(biāo)例如Counter單調(diào)遞增的累計值適合記錄總請求數(shù)、總 Token 消耗量。Histogram記錄可聚合的數(shù)值分布完美契合測量請求延遲、單次請求的 Token 數(shù)。3.2 ClickHouse 為何適合監(jiān)控數(shù)據(jù)ClickHouse 是一個開源的列式 OLAP 數(shù)據(jù)庫以其驚人的查詢速度著稱。對于監(jiān)控場景它有如下優(yōu)勢高性能聚合對時間序列數(shù)據(jù)的GROUP BY、SUM、AVG等聚合查詢極快。高壓縮比列式存儲和高效壓縮算法大幅降低存儲成本。TTL (生存時間)可以輕松為表設(shè)置數(shù)據(jù)自動過期策略符合監(jiān)控數(shù)據(jù)“近期熱、遠(yuǎn)期冷”的特點(diǎn)。豐富的表引擎MergeTree系列引擎特別是SummingMergeTree、AggregatingMergeTree是為聚合數(shù)據(jù)量身定做的。我們將使用 OpenTelemetry Collector 的clickhouseexporter將指標(biāo)直接寫入 ClickHouse 的特定表中。4. 搭建監(jiān)控基礎(chǔ)設(shè)施ClickHouse 與 Collector我們首先使用 Docker Compose 搭建數(shù)據(jù)存儲和收集層。4.1 編寫 Docker Compose 文件創(chuàng)建一個項(xiàng)目目錄ai-monitor-demo并在其中創(chuàng)建docker-compose.yml文件。# docker-compose.yml version: 3.8 services: clickhouse: image: clickhouse/clickhouse-server:24.8.2-alpine container_name: ai-monitor-clickhouse ports: - 8123:8123 # HTTP API 端口 - 9000:9000 # 原生TCP客戶端端口 volumes: - ./clickhouse/data:/var/lib/clickhouse - ./clickhouse/config.xml:/etc/clickhouse-server/config.xml - ./clickhouse/users.xml:/etc/clickhouse-server/users.xml environment: - CLICKHOUSE_DBotel - CLICKHOUSE_USERadmin - CLICKHOUSE_PASSWORDadmin123 ulimits: nproc: 65535 nofile: soft: 262144 hard: 262144 networks: - otel-network otel-collector: image: otel/opentelemetry-collector-contrib:0.104.0 container_name: ai-monitor-otel-collector command: [--config/etc/otel-collector-config.yaml] volumes: - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml ports: - 4317:4317 # OTLP gRPC 接收端口 - 4318:4318 # OTLP HTTP 接收端口 - 8889:8889 # 健康檢查/指標(biāo)端口 - 13133:13133 # 健康檢查擴(kuò)展端口 depends_on: - clickhouse networks: - otel-network grafana: image: grafana/grafana:11.2.0 container_name: ai-monitor-grafana ports: - 3000:3000 environment: - GF_SECURITY_ADMIN_PASSWORDadmin123 volumes: - ./grafana/provisioning:/etc/grafana/provisioning - ./grafana/dashboards:/var/lib/grafana/dashboards depends_on: - clickhouse networks: - otel-network networks: otel-network: driver: bridge4.2 配置 OpenTelemetry Collector創(chuàng)建otel-collector-config.yaml文件。這個配置定義了 Collector 如何接收指標(biāo)通過 OTLP以及如何將其導(dǎo)出到 ClickHouse。# otel-collector-config.yaml receivers: otlp: protocols: grpc: endpoint: 0.0.0.0:4317 http: endpoint: 0.0.0.0:4318 exporters: debug: verbosity: detailed clickhouse: endpoint: tcp://clickhouse:9000?databaseotel username: admin password: admin123 ttl: 720h # 數(shù)據(jù)保留30天 timeout: 5s logs_table_name: otel_logs traces_table_name: otel_traces metrics_table_name: otel_metrics # 針對指標(biāo)表的額外配置 metrics: # 使用 TTL 并設(shè)置存儲策略 ttl: 720h # 定義表結(jié)構(gòu)映射 OpenTelemetry 指標(biāo)到 ClickHouse 列 table_columns: - name: ResourceAttributes type: Map(LowCardinality(String), String) - name: ScopeName type: LowCardinality(String) - name: ScopeVersion type: LowCardinality(String) - name: MetricName type: LowCardinality(String) - name: MetricDescription type: String - name: MetricUnit type: LowCardinality(String) - name: Attributes type: Map(LowCardinality(String), String) - name: StartTimeUnix type: UInt64 - name: TimeUnix type: UInt64 - name: Value type: Float64 - name: Flags type: UInt32 - name: HistogramCounts type: Array(UInt64) - name: HistogramBounds type: Array(Float64) - name: Exemplars type: String processors: batch: timeout: 5s send_batch_size: 1000 extensions: health_check: endpoint: 0.0.0.0:13133 pprof: endpoint: 0.0.0.0:1777 service: extensions: [pprof, health_check] pipelines: metrics: receivers: [otlp] processors: [batch] exporters: [debug, clickhouse] # debug 用于調(diào)試生產(chǎn)可移除4.3 啟動基礎(chǔ)設(shè)施在項(xiàng)目根目錄下運(yùn)行docker-compose up -d等待所有容器啟動成功。你可以使用docker-compose logs -f查看日志。驗(yàn)證服務(wù)ClickHouse訪問http://localhost:8123/play使用用戶名admin和密碼admin123登錄。執(zhí)行SHOW DATABASES;應(yīng)能看到otel數(shù)據(jù)庫。Grafana訪問http://localhost:3000使用用戶名admin和密碼admin123登錄。Collector訪問http://localhost:13133應(yīng)返回{status:Server available}。至此監(jiān)控的后端基礎(chǔ)設(shè)施已就緒。5. 在 Python AI 應(yīng)用中集成監(jiān)控現(xiàn)在我們編寫一個簡單的 Python 應(yīng)用模擬調(diào)用 AI 模型并使用 OpenTelemetry 發(fā)送指標(biāo)。5.1 創(chuàng)建 Python 虛擬環(huán)境與依賴在項(xiàng)目根目錄外創(chuàng)建一個新的應(yīng)用目錄ai-app。mkdir ai-app cd ai-app python3 -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate安裝必要的 Python 包pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http opentelemetry-metrics pip install openai # 用于模擬AI調(diào)用5.2 編寫核心監(jiān)控與 AI 調(diào)用代碼創(chuàng)建文件app_with_monitoring.py# app_with_monitoring.py import time import random from opentelemetry import metrics from opentelemetry.sdk.metrics import MeterProvider from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter from opentelemetry.sdk.resources import Resource # 1. 定義資源標(biāo)識你的服務(wù) resource Resource.create({ service.name: ai-text-generation-service, service.version: 1.0.0, deployment.environment: demo, }) # 2. 配置指標(biāo)導(dǎo)出到 OTLP Collector (HTTP) metric_exporter OTLPMetricExporter( endpointhttp://localhost:4318/v1/metrics, # Collector 的 OTLP HTTP 端口 # 可選添加認(rèn)證頭等 ) metric_reader PeriodicExportingMetricReader(exportermetric_exporter, export_interval_millis5000) # 每5秒導(dǎo)出一次 # 3. 設(shè)置全局的 MeterProvider provider MeterProvider( resourceresource, metric_readers[metric_reader], ) metrics.set_meter_provider(provider) # 4. 創(chuàng)建 Meter meter metrics.get_meter(__name__) # 5. 創(chuàng)建我們需要的指標(biāo) # Counter: 記錄總請求數(shù)和總Token消耗 request_counter meter.create_counter( nameai.requests.total, descriptionTotal number of AI model requests, unit1, ) input_token_counter meter.create_counter( nameai.tokens.input.total, descriptionTotal number of input tokens consumed, unit1, ) output_token_counter meter.create_counter( nameai.tokens.output.total, descriptionTotal number of output tokens consumed, unit1, ) # Histogram: 記錄請求延遲和每次請求的Token數(shù)分布 request_duration_histogram meter.create_histogram( nameai.request.duration, descriptionDuration of AI model requests, unitms, ) request_token_histogram meter.create_histogram( nameai.request.tokens.total, descriptionTotal tokens (inputoutput) per request, unit1, ) def simulate_ai_call(prompt: str, model: str gpt-3.5-turbo): 模擬調(diào)用 AI 模型。 在實(shí)際項(xiàng)目中這里應(yīng)替換為真實(shí)的 OpenAI、Azure OpenAI 或本地模型的調(diào)用。 # 模擬網(wǎng)絡(luò)和計算延遲 (50ms ~ 2000ms) latency_ms random.randint(50, 2000) time.sleep(latency_ms / 1000.0) # 模擬 Token 計數(shù)簡單假設(shè)每個字符約等于 0.25 個 token input_tokens int(len(prompt) * 0.25) random.randint(1, 10) # 模擬生成長度不等的回復(fù) output_length random.randint(20, 200) output_tokens int(output_length * 0.25) random.randint(1, 20) # 模擬小概率失敗 if random.random() 0.05: # 5% 失敗率 raise Exception(Simulated AI API failure) return { content: Simulated AI response with length str(output_length), input_tokens: input_tokens, output_tokens: output_tokens, latency_ms: latency_ms, model: model } def process_user_request(user_id: str, prompt: str, model: str gpt-3.5-turbo): 處理用戶請求并記錄監(jiān)控指標(biāo)。 start_time time.time() attributes { user.id: user_id, ai.model: model, status.code: 200 # 默認(rèn)成功 } try: # 調(diào)用 AI response simulate_ai_call(prompt, model) duration_ms (time.time() - start_time) * 1000 # 記錄指標(biāo) request_counter.add(1, attributes) input_token_counter.add(response[input_tokens], attributes) output_token_counter.add(response[output_tokens], attributes) request_duration_histogram.record(duration_ms, attributes) total_tokens response[input_tokens] response[output_tokens] request_token_histogram.record(total_tokens, attributes) print(fRequest from {user_id} succeeded. Tokens: {total_tokens}, Latency: {duration_ms:.2f}ms) return response except Exception as e: duration_ms (time.time() - start_time) * 1000 # 記錄失敗的請求狀態(tài)碼標(biāo)記為錯誤 error_attributes attributes.copy() error_attributes[status.code] 500 request_counter.add(1, error_attributes) request_duration_histogram.record(duration_ms, error_attributes) print(fRequest from {user_id} failed: {e}) return None if __name__ __main__: print(Starting AI service with OpenTelemetry monitoring...) # 模擬連續(xù)處理一些請求 users [user_001, user_002, user_003, user_004] models [gpt-3.5-turbo, gpt-4] prompts [ Explain quantum computing in simple terms., Write a Python function to calculate Fibonacci sequence., What are the benefits of renewable energy?, Summarize the history of the Internet. ] for i in range(20): # 模擬20個請求 user random.choice(users) model random.choice(models) prompt random.choice(prompts) process_user_request(user, prompt, model) time.sleep(random.uniform(0.5, 2.0)) # 模擬隨機(jī)請求間隔 print(Simulation finished. Metrics are being exported...) # 等待指標(biāo)導(dǎo)出器完成最后的推送 time.sleep(10) print(Done.)5.3 運(yùn)行應(yīng)用并查看數(shù)據(jù)確保docker-compose服務(wù)仍在運(yùn)行。在ai-app目錄下運(yùn)行 Python 腳本python app_with_monitoring.py觀察控制臺輸出會看到模擬的請求成功與失敗信息。登錄 ClickHouse (http://localhost:8123/play)查詢是否已收到指標(biāo)數(shù)據(jù)USE otel; SELECT DISTINCT MetricName FROM otel_metrics ORDER BY MetricName;你應(yīng)該能看到ai.requests.total,ai.request.duration等我們定義的指標(biāo)名。查詢具體的指標(biāo)數(shù)據(jù)SELECT toDateTime(TimeUnix/1000000000) as time, MetricName, Attributes[user.id] as user, Attributes[ai.model] as model, Value, HistogramBounds, HistogramCounts FROM otel_metrics WHERE MetricName ai.request.duration ORDER BY time DESC LIMIT 5;此查詢會顯示最近幾條請求延遲的直方圖數(shù)據(jù)。6. 在 Grafana 中可視化監(jiān)控數(shù)據(jù)數(shù)據(jù)已進(jìn)入 ClickHouse現(xiàn)在我們在 Grafana 中創(chuàng)建儀表盤。6.1 配置 ClickHouse 數(shù)據(jù)源登錄 Grafana (http://localhost:3000)默認(rèn)賬號admin/admin123。點(diǎn)擊左側(cè)齒輪圖標(biāo)Configuration-Data sources。點(diǎn)擊Add data source搜索并選擇ClickHouse。配置連接Name:ClickHouse-OTelHost:clickhouse:8123注意因?yàn)?Grafana 和 ClickHouse 在同一 Docker 網(wǎng)絡(luò)otel-network下所以可以用服務(wù)名Database:otelUser:adminPassword:admin123Protocol:HTTP點(diǎn)擊Save test應(yīng)顯示 “Data source is working”。6.2 創(chuàng)建監(jiān)控儀表盤我們可以創(chuàng)建幾個關(guān)鍵面板面板 1請求速率與錯誤率查詢(請求總量)SELECT $timeSeries as t, count(*) as value FROM $table WHERE $timeFilter AND MetricName ai.requests.total GROUP BY t ORDER BY t查詢(錯誤請求量屬性status.code500)SELECT $timeSeries as t, count(*) as value FROM $table WHERE $timeFilter AND MetricName ai.requests.total AND Attributes[status.code] 500 GROUP BY t ORDER BY t可視化使用Stat或Time series圖表。可以計算錯誤率錯誤數(shù) / 總數(shù) * 100%。面板 2平均響應(yīng)延遲與 P99 延遲查詢(平均延遲需要利用直方圖數(shù)據(jù)計算這里簡化查詢平均值)SELECT $timeSeries as t, avg(Value) as value FROM $table WHERE $timeFilter AND MetricName ai.request.duration AND Attributes[status.code] 200 -- 只看成功的請求 GROUP BY t ORDER BY t注意更精確的百分位數(shù)計算需要在查詢時展開HistogramBounds和HistogramCounts列或使用 ClickHouse 的quantile函數(shù)對Value進(jìn)行估算。生產(chǎn)環(huán)境建議對直方圖數(shù)據(jù)進(jìn)行預(yù)聚合。面板 3Token 消耗趨勢按用戶/模型查詢(總輸入 Token)SELECT $timeSeries as t, sum(Value) as value FROM $table WHERE $timeFilter AND MetricName ai.tokens.input.total GROUP BY t ORDER BY t查詢(按模型分組)SELECT $timeSeries as t, Attributes[ai.model] as metric, sum(Value) as value FROM $table WHERE $timeFilter AND MetricName ai.tokens.input.total GROUP BY t, metric ORDER BY t, metric可視化使用Time series圖表并開啟Stack模式可以清晰看到不同模型的 Token 消耗占比。面板 4單次請求 Token 數(shù)量分布查詢SELECT Value as tokens_per_request FROM $table WHERE $timeFilter AND MetricName ai.request.tokens.total AND Attributes[status.code] 200可視化使用Histogram圖表可以直觀看到大部分請求消耗的 Token 范圍有助于識別異常值例如提示詞泄露導(dǎo)致的長文本輸出。將這些面板組合在一個儀表盤中你就得到了一個專屬的 AI 服務(wù)監(jiān)控看板可以實(shí)時觀察服務(wù)的健康度、性能與成本。7. 常見問題與排查思路在搭建和使用過程中你可能會遇到以下問題問題現(xiàn)象可能原因排查思路Python 應(yīng)用啟動報錯提示opentelemetry-exporter-otlp相關(guān)錯誤依賴版本不兼容或未安裝1. 檢查pip list確認(rèn)包已安裝。2. 查看 OpenTelemetry Python SDK 和 Exporter 的版本兼容性盡量使用較新且版本匹配的包。應(yīng)用運(yùn)行后ClickHouse 中查不到數(shù)據(jù)Collector 配置錯誤或網(wǎng)絡(luò)不通1. 檢查 Collector 容器日志docker-compose logs otel-collector。2. 確認(rèn) Python 應(yīng)用中endpoint指向正確的 Collector 地址和端口 (http://localhost:4318)。3. 在 Collector 配置中啟用debugexporter查看是否收到數(shù)據(jù)。Grafana 中查詢數(shù)據(jù)報錯或?yàn)榭諗?shù)據(jù)源配置錯誤或 SQL 查詢語法問題1. 在 Grafana 的Explore頁面使用配置好的 ClickHouse 數(shù)據(jù)源執(zhí)行簡單查詢?nèi)鏢ELECT 1測試連接。2. 檢查 SQL 中的表名 (otel_metrics)、字段名是否與 ClickHouse 中實(shí)際創(chuàng)建的表一致。3. 確認(rèn)查詢的時間范圍 ($timeFilter) 內(nèi)有數(shù)據(jù)。監(jiān)控數(shù)據(jù)延遲很高Collector 的batch處理器配置或 MetricReader 導(dǎo)出間隔過長1. 檢查otel-collector-config.yaml中batch處理器的timeout建議 5-10s。2. 檢查 Python 代碼中PeriodicExportingMetricReader的export_interval_millis建議 5000-10000 ms。3. 對于需要近實(shí)時監(jiān)控的場景可以適當(dāng)縮短這些間隔但會增加 Collector 負(fù)載。ClickHouse 磁盤空間增長過快數(shù)據(jù)沒有設(shè)置 TTL 或監(jiān)控指標(biāo)過于頻繁1. 確認(rèn) Collector 配置中ttl: 720h30天已生效。2. 可以在 ClickHouse 中為otel_metrics表額外設(shè)置 TTLALTER TABLE otel_metrics MODIFY TTL TimeUnix INTERVAL 30 DAY。3. 評估指標(biāo)發(fā)射頻率非核心指標(biāo)可以降低頻率。8. 最佳實(shí)踐與工程建議將監(jiān)控系統(tǒng)投入生產(chǎn)環(huán)境時需要考慮更多工程細(xì)節(jié)。8.1 監(jiān)控指標(biāo)設(shè)計遵循命名規(guī)范使用點(diǎn)分隔的命名方式如ai.request.duration、business.order.value。添加前綴如ai.避免沖突。精心設(shè)計屬性 (Attributes)屬性是進(jìn)行數(shù)據(jù)下鉆 (drill-down) 分析的維度。像user.id、ai.model、prompt.type、status.code都是非常有價值的屬性。但注意高基數(shù)字段如直接使用用戶ID可能導(dǎo)致查詢變慢可以考慮使用哈希值或分組。區(qū)分指標(biāo)類型Counter用于只增不減的值請求數(shù)、Token總數(shù)。Histogram用于記錄分布延遲、包大小、單個請求Token數(shù)。Gauge用于可增可減的瞬時值并發(fā)請求數(shù)、內(nèi)存使用量。8.2 性能與成本優(yōu)化采樣與聚合對于極高并發(fā)的服務(wù)不是每個請求都需要記錄完整的直方圖。可以在 SDK 端或 Collector 端配置采樣率或使用AggregatingMeterProvider在客戶端進(jìn)行預(yù)聚合。ClickHouse 表引擎優(yōu)化生產(chǎn)環(huán)境建議使用AggregatingMergeTree或SummingMergeTree引擎來存儲預(yù)聚合后的數(shù)據(jù)而不是原始的指標(biāo)數(shù)據(jù)這能極大提升查詢性能和降低存儲成本。這通常需要在 Collector 或一個獨(dú)立的聚合服務(wù)中完成。控制數(shù)據(jù)粒度根據(jù)需求決定數(shù)據(jù)存儲的粒度。例如原始數(shù)據(jù)保留7天按小時聚合的數(shù)據(jù)保留30天按天聚合的數(shù)據(jù)保留1年。8.3 生產(chǎn)環(huán)境部署Collector 高可用生產(chǎn)環(huán)境至少部署兩個 Collector 實(shí)例前端通過負(fù)載均衡器如 Nginx分發(fā)流量避免單點(diǎn)故障。安全為 ClickHouse 和 Grafana 配置強(qiáng)密碼并考慮網(wǎng)絡(luò)隔離如將 ClickHouse 置于內(nèi)網(wǎng)不暴露8123端口到公網(wǎng)。OTLP 端點(diǎn)可以考慮啟用 TLS 加密傳輸。資源限制為 Docker 容器或 Pod 設(shè)置合理的 CPU 和內(nèi)存限制防止某個組件異常拖垮整個主機(jī)。8.4 告警集成監(jiān)控的最終目的是發(fā)現(xiàn)問題并及時響應(yīng)。在 Grafana 中可以基于我們創(chuàng)建的儀表盤設(shè)置告警規(guī)則延遲告警當(dāng)ai.request.duration的 P95 值超過 5 秒時觸發(fā)。錯誤率告警當(dāng)錯誤請求率 (status.code500的請求占比) 連續(xù) 5 分鐘超過 1% 時觸發(fā)。Token 消耗異常告警當(dāng)某個用戶的每小時 Token 消耗量突增 10 倍時觸發(fā)可能提示提示詞被惡意利用或程序漏洞。通過將 Grafana 告警連接到 Slack、釘釘、PagerDuty 等通知渠道團(tuán)隊可以在第一時間獲知服務(wù)異常。從環(huán)境搭建、應(yīng)用埋點(diǎn)、數(shù)據(jù)存儲到可視化告警我們完成了一個完整的 AI 服務(wù)可觀測性閉環(huán)。這套方案的核心優(yōu)勢在于標(biāo)準(zhǔn)化和可擴(kuò)展性——OpenTelemetry 讓你未來可以無縫切換監(jiān)控后端ClickHouse 的高性能則確保了即使面對海量監(jiān)控數(shù)據(jù)查詢也能快速響應(yīng)。