用 MCP 擴(kuò)展 Cursor 能力:解鎖 Sentry 服務(wù)數(shù)據(jù)新玩法
1.MCP 簡(jiǎn)介
MCP(Model Context Protocol,模型上下文協(xié)議)是由 Anthropic 推出的一種開(kāi)放標(biāo)準(zhǔn),旨在統(tǒng)一大型語(yǔ)言模型(LLM)與外部數(shù)據(jù)源和工具之間的通信協(xié)議。
使用模型上下文協(xié)議(MCP)可以構(gòu)建服務(wù)器,向LLM應(yīng)用程序公開(kāi)數(shù)據(jù)和功能。MCP 服務(wù)器可以完成的功能如下:
- 通過(guò)資源(Resources)暴露數(shù)據(jù)(類似 GET 請(qǐng)求的執(zhí)行接口;它們用于將信息加載到 LLM 的上下文中);
- 通過(guò)工具(Tools)提供功能(類似 POST 請(qǐng)求的執(zhí)行接口;它們用于執(zhí)行代碼或者產(chǎn)生其他附帶影響);
- 通過(guò)提示(Prompts)定義交互模式(類似一個(gè)服務(wù)列表;可以用來(lái)查詢服務(wù)器提供哪些服務(wù),需要哪些參數(shù)等)。
MCP 的主要目的在于解決當(dāng)前 AI模型因數(shù)據(jù)孤島限制而無(wú)法充分發(fā)揮潛力的難題。通過(guò) MCP,AI應(yīng)用能夠安全地訪問(wèn)和操作本地及遠(yuǎn)程數(shù)據(jù),為 AI 應(yīng)用提供了連接萬(wàn)物的接口。
在當(dāng)前 AI應(yīng)用開(kāi)發(fā)中,我們經(jīng)常需要讓 AI模型與現(xiàn)有的業(yè)務(wù)系統(tǒng)進(jìn)行交互。例如,查詢數(shù)據(jù)庫(kù)、調(diào)用監(jiān)控系統(tǒng) API 、分析日志等。MCP 提供了一種標(biāo)準(zhǔn)化的方式來(lái)構(gòu)建這種交互,使 AI 模型能夠"看見(jiàn)"外部世界的數(shù)據(jù)。
2.MCP 的核心優(yōu)勢(shì)
- 能力擴(kuò)展:使 AI 模型能夠超越其訓(xùn)練數(shù)據(jù)的限制,獲取實(shí)時(shí)外部信息;
- 標(biāo)準(zhǔn)化接口:提供統(tǒng)一的接口規(guī)范,簡(jiǎn)化服務(wù)集成過(guò)程;
- 安全可控:通過(guò)明確的權(quán)限管理和訪問(wèn)控制,保障數(shù)據(jù)安全;
- 低代碼集成:減少編寫膠水代碼的需求,降低開(kāi)發(fā)成本;
- 實(shí)時(shí)數(shù)據(jù)訪問(wèn):讓 AI能夠基于最新數(shù)據(jù)做出決策和回復(fù)。
3.MCP可以實(shí)現(xiàn)的功能舉例
以下服務(wù)是官方提供或者第三方通過(guò)MCP協(xié)議實(shí)現(xiàn)的一些服務(wù)工具。由TypeScript或者 Python SDK實(shí)現(xiàn),詳細(xì)說(shuō)明以及更多例子可以參見(jiàn)官方文檔:官方文檔(https://github.com/modelcontextprotocol/servers)
- AWS 知識(shí)庫(kù)檢索 - 使用 Bedrock Agent Runtime 從 AWS 知識(shí)庫(kù)中檢索信息;
- Brave 搜索 - 使用 Brave 的搜索 API進(jìn)行網(wǎng)絡(luò)和本地搜索;
- EverArt - 使用各種模型進(jìn)行 AI圖像生成;
- Everything - 參考/測(cè)試服務(wù)器,包含提示、資源和工具;
- Fetch - 網(wǎng)絡(luò)內(nèi)容獲取和轉(zhuǎn)換,提高 LLM 使用效率;
- 文件系統(tǒng) - 具有可配置訪問(wèn)控制的安全文件操作;
- Git- 用于讀取、搜索和操作 Git 倉(cāng)庫(kù)的工具;
- GitHub - 倉(cāng)庫(kù)管理、文件操作和 GitHub API集成;
- GitLab - GitLab API,支持項(xiàng)目管理;
- Google Drive - Google Drive 文件訪問(wèn)和搜索功能;
- Google 地圖 - 位置服務(wù)、路線指引和地點(diǎn)詳情;
- 記憶系統(tǒng) - 基于知識(shí)圖譜的持久化記憶系統(tǒng);
- PostgreSQL - 具有架構(gòu)檢查功能的只讀數(shù)據(jù)庫(kù)訪問(wèn);
- Puppeteer - 瀏覽器自動(dòng)化和網(wǎng)頁(yè)抓?。?/li>
- Redis - 與 Redis 鍵值存儲(chǔ)交互;
- Sentry - 從 Sentry.io 檢索和分析問(wèn)題;
- Sequential Thinking - 通過(guò)思維序列進(jìn)行動(dòng)態(tài)和反思性問(wèn)題解決;
- Slack - 頻道管理和消息發(fā)送功能;
- SQLite - 數(shù)據(jù)庫(kù)交互和商業(yè)智能功能。
4.以 Sentry 服務(wù)為例的 MCP 實(shí)踐
4.1 背景與實(shí)現(xiàn)的功能
在我們的項(xiàng)目中,我們使用Sentry 作為 bug上報(bào)平臺(tái)。數(shù)據(jù)可以通過(guò)接口獲取,其與 MCP服務(wù)結(jié)合,能夠便捷地將數(shù)據(jù)接入 AI,可以更方便地分析 crash原因和查詢崩潰率等數(shù)據(jù)。官方提供的 demo 程序,更是為我們進(jìn)一步擴(kuò)展 Sentry工具功能提供了很好的參考示例。 借助 Sentry接入 MCP協(xié)議,我們可以只將 bug ID或問(wèn)題鏈接提交給 cursor,便能迅速獲取詳細(xì)的 bug 信息以及可能的解決方案,這可以顯著提升問(wèn)題排查與解決的效率。
同時(shí),我們把 Sentry統(tǒng)計(jì)信息也接入系統(tǒng),賦予了 cursor訪問(wèn)各版本崩潰率數(shù)據(jù)以及全版本綜合崩潰率數(shù)據(jù)的權(quán)限。AI能夠據(jù)此輸出直觀的對(duì)比圖表或者數(shù)據(jù)。
不僅如此,為進(jìn)一步豐富 Sentry MCP 工具的功能,我們還將后端應(yīng)用性能監(jiān)控(APM)數(shù)據(jù)整合至該服務(wù)中。如此一來(lái),cursor可直接查詢到更為全面、豐富的應(yīng)用信息,全方位提升了數(shù)據(jù)的可獲取性與利用價(jià)值。
4.2 Sentry MCP服務(wù)組件功能結(jié)構(gòu)
Sentry MCP服務(wù)組件功能結(jié)構(gòu)圖如下:
- 程序流程 - 程序入口:通過(guò)main函數(shù)啟動(dòng)程序,接收Sentry和SNS身份驗(yàn)證令牌;- 服務(wù)器創(chuàng)建:serve函數(shù)創(chuàng)建MCP服務(wù)器并注冊(cè)各種處理程序;- 請(qǐng)求處理:當(dāng) AI助手發(fā)起工具調(diào)用請(qǐng)求時(shí),handle_call_tool函數(shù)依據(jù)工具名稱進(jìn)行請(qǐng)求的路由分發(fā);- 數(shù)據(jù)獲?。簩iT的處理函數(shù)通過(guò)外部API獲取數(shù)據(jù),并將其封裝在相應(yīng)的數(shù)據(jù)類中;- 響應(yīng)生成:數(shù)據(jù)類提供方法將數(shù)據(jù)轉(zhuǎn)換為所需的格式,返回給AI助手。
- 主要組件數(shù)據(jù)類:- SentryIssueData:存儲(chǔ)Sentry錯(cuò)誤和crash信息,包括標(biāo)題、ID、狀態(tài)和堆棧跟蹤;- SentrySessionStatsData:存儲(chǔ)Sentry會(huì)話統(tǒng)計(jì)數(shù)據(jù),如崩潰率、用戶數(shù)等;- ApkHistoryData:存儲(chǔ)APK檢測(cè)歷史數(shù)據(jù),包括版本、大小和各組件信息。處理函數(shù):- handle_sentry_issue:獲取特定Sentry問(wèn)題詳情;- handle_session_stats:獲取會(huì)話統(tǒng)計(jì)數(shù)據(jù),如崩潰率和穩(wěn)定性指標(biāo);- handle_apk_history:獲取APK歷史數(shù)據(jù),包括大小和組件分析。服務(wù)器配置:- serve:配置MCP服務(wù)器,注冊(cè)工具、提示和處理程序;- handle_call_tool:分發(fā)工具調(diào)用請(qǐng)求到相應(yīng)的處理函數(shù)。
4.3 功能實(shí)現(xiàn)
MCP協(xié)議有Python、Java、Kotlin等語(yǔ)言的SDK,由于Python使用最為普遍,我們這里使用PythonSDK來(lái)實(shí)現(xiàn)。
4.3.1 安裝MCP
pip install mcp
4.3.2 功能入口
創(chuàng)建server.py文件作為服務(wù)程序的代碼文件,以下所列代碼都是在這個(gè)代碼文件中。下面main函數(shù)是程序入口函數(shù):
#server.py
def main(auth_token: str, sns_token: str = None):
async def _run():
async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
server = await serve(auth_token, sns_token)
await server.run(
read_stream,
write_stream,
InitializationOptions(
server_name="sentry",
server_versinotallow="0.4.1",
capabilities=server.get_capabilities(
notification_optinotallow=NotificationOptions(),
experimental_capabilities={},
),
),
)
asyncio.run(_run())
if __name__ == "__main__":
# 直接調(diào)用main函數(shù)
main()
main函數(shù)的功能如下:
- 創(chuàng)建基于stdio的服務(wù)器通信通道;
- serve函數(shù)初始化MCP服務(wù)器實(shí)例;
- 配置服務(wù)器初始化選項(xiàng);
- 啟動(dòng)服務(wù)器運(yùn)行循環(huán)。
4.3.3 服務(wù)器實(shí)例創(chuàng)建
下面是簡(jiǎn)化版的serve函數(shù):
#server.py
async def serve(auth_token: str, sns_token: str = None) -> Server:
server = Server("sentry")
http_client = httpx.AsyncClient(base_url=SENTRY_API_BASE)
apk_http_client = httpx.AsyncClient(base_url=APK_API_BASE)
@server.list_prompts()
async def handle_list_prompts() -> list[types.Prompt]:
prompts = [
types.Prompt(
name="sentry-issue",
descriptinotallow="通過(guò)ID或URL獲取Sentry問(wèn)題詳情",
arguments=[
],
),
types.Prompt(
name="session-stats",
descriptinotallow="獲取Sentry會(huì)話統(tǒng)計(jì)數(shù)據(jù)和崩潰率",
arguments=[
],
),
types.Prompt(
name="apk-history",
descriptinotallow="獲取APK檢測(cè)歷史數(shù)據(jù)",
arguments=[]
)
]
return prompts
@server.get_prompt()
async def handle_get_prompt(
name: str, arguments: dict[str, str] | None
) -> types.GetPromptResult:
if name == "sentry-issue":
...
return issue_data.to_prompt_result()
elif name == "session-stats":
...
return stats_data.to_prompt_result()
elif name == "apk-history":
...
return history_data.to_prompt_result()
else:
raise ValueError(f"Unknown prompt: {name}")
@server.list_tools()
async def handle_list_tools() -> list[types.Tool]:
tools = [
types.Tool(
name="get_sentry_issue",
),
types.Tool(
name="get_sentry_session_stats",
) ,
types.Tool(
name="get_apk_history",
)
]
return tools
@server.call_tool()
async def handle_call_tool(
name: str, arguments: dict | None
) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
if name == "get_sentry_issue":
return issue_data.to_tool_result()
elif name == "get_sentry_session_stats":
return stats_data.to_tool_result()
elif name == "get_apk_history":
return history_data.to_tool_result()
else:
raise ValueError(f"Unknown tool: {name}")
return server
serve函數(shù)是這個(gè)MCP Sentry服務(wù)的核心組件,負(fù)責(zé)創(chuàng)建、配置和返回一個(gè)完整的MCP服務(wù)器實(shí)例。它通過(guò)四個(gè)主要組件構(gòu)建了完整服務(wù):
- 提示列表:定義可用的查詢服務(wù)(問(wèn)題詳情、崩潰率統(tǒng)計(jì)、APK歷史);
- 提示處理器:執(zhí)行查詢邏輯并返回結(jié)果;
- 工具列表:注冊(cè)可調(diào)用的工具集合;
- 工具調(diào)用處理器:處理具體工具調(diào)用并獲取數(shù)據(jù) 整體功能是將Sentry和APK監(jiān)控系統(tǒng)的復(fù)雜API調(diào)用封裝成結(jié)構(gòu)化接口,方便AI助手獲取崩潰報(bào)告、穩(wěn)定性數(shù)據(jù)和APK分析信息。
4.4 三個(gè)查詢功能的實(shí)現(xiàn)
4.4.1 Sentry問(wèn)題詳情獲取功能實(shí)現(xiàn)
handle_sentry_issue函數(shù)是MCP Sentry服務(wù)的核心組件之一,它通過(guò)問(wèn)題ID或URL獲取Sentry問(wèn)題的詳細(xì)信息,包括問(wèn)題標(biāo)題、狀態(tài)、級(jí)別、首次和最后出現(xiàn)時(shí)間、事件數(shù)量,以及最關(guān)鍵的堆棧跟蹤信息。下面的問(wèn)題詳情的獲取主函數(shù)功能:
#server.py
asyncdef handle_sentry_issue(
http_client: httpx.AsyncClient, auth_token: str, issue_id_or_url: str
) -> SentryIssueData:
try:
# 提取問(wèn)題ID
issue_id = extract_issue_id(issue_id_or_url)
# 獲取問(wèn)題詳情
response = await http_client.get(
f"organizations/xxx/issues/{issue_id}/",
headers={"Authorization": f"Bearer {auth_token}"}
)
if response.status_code == 401:
raise McpError(
"Error: Unauthorized. Please check your MCP_SENTRY_AUTH_TOKEN token."
)
response.raise_for_status()
issue_data = response.json()
# 獲取問(wèn)題哈希值
hashes_response = await http_client.get(
f"organizations/xxx/issues/{issue_id}/hashes/",
headers={"Authorization": f"Bearer {auth_token}"},
)
hashes_response.raise_for_status()
hashes = hashes_response.json()
ifnot hashes:
raise McpError("No Sentry events found for this issue")
# 獲取最新事件并生成堆棧跟蹤
latest_event = hashes[0]["latestEvent"]
stacktrace = create_stacktrace(latest_event)
# 返回格式化的問(wèn)題數(shù)據(jù)
return SentryIssueData(
title=issue_data["title"],
issue_id=issue_id,
status=issue_data["status"],
level=issue_data["level"],
first_seen=issue_data["firstSeen"],
last_seen=issue_data["lastSeen"],
count=issue_data["count"],
stacktrace=stacktrace
)
except SentryError as e:
raise McpError(str(e))
except httpx.HTTPStatusError as e:
raise McpError(f"Error fetching Sentry issue: {str(e)}")
except Exception as e:
raise McpError(f"An error occurred: {str(e)}")
為了簡(jiǎn)化使用并確保數(shù)據(jù)一致性,我們?cè)谧钚掳姹局袑?duì)環(huán)境和項(xiàng)目做了固定配置:
- 環(huán)境(environment):固定為 ["flavorsOnline_arm64"]
- 項(xiàng)目 ID(project):固定為 [6]
這樣用戶在查詢時(shí)不需要每次都指定這些參數(shù)。
4.4.2 Sentry會(huì)話統(tǒng)計(jì)數(shù)據(jù)獲取功能實(shí)現(xiàn)
handle_session_stats函數(shù)是Sentry MCP服務(wù)的另一個(gè)核心組件,專門用于獲取應(yīng)用的會(huì)話統(tǒng)計(jì)數(shù)據(jù),包括崩潰率、用戶數(shù)量、會(huì)話持續(xù)時(shí)間等關(guān)鍵指標(biāo)。這些數(shù)據(jù)對(duì)于監(jiān)控應(yīng)用穩(wěn)定性、分析版本質(zhì)量和追蹤用戶體驗(yàn)至關(guān)重要。
#server.py
asyncdef handle_session_stats(
http_client: httpx.AsyncClient,
auth_token: str,
organization: str,
field: list[str],
start: str = None,
end: str = None,
environment: list[str] = None,
stats_period: str = None,
project: list[int] = None,
per_page: int = None,
interval: str = None,
group_by: list[str] = None,
order_by: str = None,
include_totals: int = 1,
include_series: int = 1,
query: str = None
) -> SentrySessionStatsData:
try:
# 構(gòu)建查詢參數(shù)
params = {"field": field}
if start:
params["start"] = start
if end:
params["end"] = end
if environment:
params["environment"] = environment
if stats_period:
params["statsPeriod"] = stats_period
if project:
params["project"] = project
if per_page:
params["per_page"] = per_page
if interval:
params["interval"] = interval
if group_by:
params["groupBy"] = group_by
if order_by:
params["orderBy"] = order_by
if include_totals isnotNone:
params["includeTotals"] = include_totals
if include_series isnotNone:
params["includeSeries"] = include_series
if query:
params["query"] = query
# 發(fā)送請(qǐng)求
response = await http_client.get(
f"organizations/{organization}/sessions/",
headers={"Authorization": f"Bearer {auth_token}"},
params=params
)
if response.status_code == 401:
raise McpError(
"Error: Unauthorized. Please check your MCP_SENTRY_AUTH_TOKEN token."
)
response.raise_for_status()
data = response.json()
stats_data = SentrySessionStatsData(
organizatinotallow=organization,
start_time=data.get("start", ""),
end_time=data.get("end", ""),
intervals=data.get("intervals", []),
groups=data.get("groups", []),
query=data.get("query", "")
)
report_file_path = generate_crash_rate_html_report(
data=stats_data,
params=params
)
stats_data.report_file_path = report_file_path
return stats_data
except httpx.HTTPStatusError as e:
raise McpError(f"Error fetching Sentry session statistics: {str(e)}")
except Exception as e:
raise McpError(f"An error occurred: {str(e)}")
- 功能亮點(diǎn) - 靈活的查詢參數(shù):支持多種篩選條件,如時(shí)間范圍、環(huán)境、項(xiàng)目ID、查詢表達(dá)式等;- 豐富的統(tǒng)計(jì)指標(biāo):提供多種會(huì)話相關(guān)指標(biāo),如: 會(huì)話總數(shù) ( sum(session))獨(dú)立用戶數(shù) (count_unique(user))平均會(huì)話時(shí)長(zhǎng) (avg(session.duration))會(huì)話時(shí)長(zhǎng)分位數(shù) (p50/p75/p90/p95/p99/max(session.duration))用戶崩潰率 (crash_rate(user))會(huì)話崩潰率 (crash_rate(session))用戶崩潰免除率 (crash_free_rate(user))會(huì)話崩潰免除率 (crash_free_rate(session))- 數(shù)據(jù)系列和匯總:同時(shí)支持時(shí)間序列數(shù)據(jù)和匯總數(shù)據(jù),生成html文件,便于趨勢(shì)分析和整體評(píng)估;- 分組和排序:支持對(duì)數(shù)據(jù)進(jìn)行分組和排序,便于比較分析不同維度的數(shù)據(jù)。
通過(guò)這一功能,使用cursor能夠幫助我們監(jiān)控和分析應(yīng)用的穩(wěn)定性表現(xiàn),及時(shí)發(fā)現(xiàn)潛在問(wèn)題,提供數(shù)據(jù)支持以優(yōu)化用戶體驗(yàn)和應(yīng)用質(zhì)量。
4.4.3 APK檢測(cè)歷史數(shù)據(jù)獲取功能實(shí)現(xiàn)
handle_apk_history函數(shù)是Sentry MCP服務(wù)中專門用于獲取和分析APK檢測(cè)歷史數(shù)據(jù)的組件。它能夠追蹤應(yīng)用各版本的體積變化、組件大小分布和版本迭代情況。
#server.py
asyncdef handle_apk_history(
http_client: httpx.AsyncClient,
sns_token: str
) -> ApkHistoryData:
try:
response = await http_client.get(
"getHistory/0",
headers={"sns_token": sns_token}
)
if response.status_code == 401:
raise McpError(
"Error: Unauthorized. Please check your SNS token."
)
response.raise_for_status()
data = response.json()
# 從新的API響應(yīng)結(jié)構(gòu)中獲取數(shù)據(jù)
apkData = ApkHistoryData(
apk_list=data.get("data", {}).get("apkList", []),
total_count=data.get("data", {}).get("totalCount", 0)
)
report_file_path = generate_apk_history_html_report(
data=apkData
)
apkData.report_file_path = report_file_path
return apkData
except httpx.HTTPStatusError as e:
raise McpError(f"Error fetching APK history data: {str(e)}")
except Exception as e:
raise McpError(f"An error occurred: {str(e)}")
這些信息源自我們內(nèi)部 應(yīng)用性能監(jiān)控(APM)接口,它詳細(xì)呈現(xiàn)了 APK的相關(guān)內(nèi)容,具體涵蓋:
- 基本信息:APK 的版本、版本號(hào)以及名稱;
- 大小詳情:APK的總大小,以及實(shí)際下載大??;
- 組件分析:對(duì) APK 各組件,即Assets、Dex、Lib以及資源部分的大小進(jìn)行剖析;
- 元數(shù)據(jù):包含時(shí)間戳、文件路徑、備注信息,以及特性描述等。 此外,這些數(shù)據(jù)以結(jié)構(gòu)化形式整合,輸出到html文件中,將復(fù)雜信息有序組織,方便后續(xù)進(jìn)行深入分析與直觀展示。
4.4.4 在cursor中集成
在cursor的設(shè)置中添加MCP服務(wù),Type選擇command,然后在Command中輸入python執(zhí)行程序,保存后,可以在cursor對(duì)話框中使用,添加的界面如圖所示:
選擇Type時(shí),還有另一種Type是sse,sse是服務(wù)器發(fā)送事件(Server-Sent Events,SSE)它是一種允許服務(wù)器向客戶端實(shí)時(shí)推送數(shù)據(jù)的 Web API。SSE建立了一個(gè)單向的HTTP連接,服務(wù)器可以在有新數(shù)據(jù)時(shí)隨時(shí)向客戶端發(fā)送消息,而客戶端只需監(jiān)聽(tīng)服務(wù)器的推送。我們Sentry MCP這里只使用了主動(dòng)獲取數(shù)據(jù)的方式,因此這里選擇了command命令行的方式。command完整的命令如下所示:
python3 /Users/xxx/server.py --auth-token xxx sns-token xxx
其中xxx是我們sentry平臺(tái)和應(yīng)用性能監(jiān)控(APM)的接口token
4.5 效果展示
4.5.1 查詢崩潰率數(shù)據(jù)
使用handle_session_stats函數(shù)可以輕松獲取應(yīng)用的崩潰率數(shù)據(jù),例如在cursor中輸入:幫我查詢6.6.0版本和6.5.0版本最近14天的崩潰率詳情,輸出html結(jié)果如下:
4.5.2 查詢bug詳情
在cursor中輸入:幫我查詢這個(gè)bug的詳細(xì)信息644,請(qǐng)求cursor結(jié)果如下:
Sentry問(wèn)題分析報(bào)告
我已經(jīng)查詢到關(guān)于您提供的Sentry問(wèn)題的詳細(xì)信息。這是一個(gè)發(fā)生在flavorsOnline_arm64環(huán)境中的項(xiàng)目6的錯(cuò)誤:
錯(cuò)誤概覽
錯(cuò)誤類型:RemoteServiceException$CannotDeliverBroadcastException
錯(cuò)誤描述:can't deliver broadcast
問(wèn)題ID:644
狀態(tài):未解決
嚴(yán)重級(jí)別:致命(fatal)
首次出現(xiàn):2024-10-03 04:36:33
最近出現(xiàn):2025-03-21 10:44:02
事件計(jì)數(shù):18次
堆棧跟蹤
錯(cuò)誤發(fā)生在Android系統(tǒng)的廣播傳遞機(jī)制中,堆棧跟蹤顯示:
ZygoteInit.java:954 in main
RuntimeInit.java:559 in run
Method.java:None in invoke
ActivityThread.java:8395 in main
Looper.java:300 in loop
Looper.java:211 in loopOnce
Handler.java:106 in dispatchMessage
ActivityThread.java:2349 in handleMessage
None:0 in -$$Nest$mthrowRemoteServiceException
ActivityThread.java:2087 in throwRemoteServiceException
崩潰率分析
根據(jù)過(guò)去7天的會(huì)話統(tǒng)計(jì):
崩潰率:約0.0001 (0.01%)
無(wú)崩潰率:約0.9999 (99.99%)
總會(huì)話數(shù):1,239,555
雖然崩潰率較低,但由于這是一個(gè)致命錯(cuò)誤,且在近期(3月21日)仍有發(fā)生,應(yīng)該引起關(guān)注。
問(wèn)題分析
錯(cuò)誤性質(zhì):這是一個(gè)與Android廣播機(jī)制相關(guān)的RemoteServiceException,表明應(yīng)用嘗試發(fā)送一個(gè)廣播,但系統(tǒng)無(wú)法傳遞。
可能原因:
廣播接收器不存在或已被卸載
目標(biāo)組件權(quán)限問(wèn)題
系統(tǒng)資源限制導(dǎo)致廣播傳遞失敗
特定于arm64架構(gòu)的問(wèn)題
影響范圍:
錯(cuò)誤發(fā)生在flavorsOnline_arm64環(huán)境
相對(duì)較低的崩潰率(0.01%)表明這可能是特定設(shè)備或特定條件下才會(huì)觸發(fā)的問(wèn)題
建議解決方案
防御性編程:
在發(fā)送廣播前檢查接收器是否存在
使用try-catch塊包裝廣播發(fā)送代碼
錯(cuò)誤位置定位:
檢查ActivityThread.java:2087處的throwRemoteServiceException方法調(diào)用點(diǎn)
找出應(yīng)用中哪些地方發(fā)送了可能觸發(fā)此異常的廣播
設(shè)備/版本針對(duì)性修復(fù):
由于這個(gè)問(wèn)題僅在arm64架構(gòu)出現(xiàn),可以考慮為該架構(gòu)添加特定的兼容性代碼
監(jiān)控計(jì)劃:
雖然崩潰率低,但應(yīng)繼續(xù)監(jiān)控,特別是在新版本發(fā)布后
由于這個(gè)錯(cuò)誤是與Android系統(tǒng)廣播機(jī)制相關(guān)的,建議查看應(yīng)用中所有發(fā)送廣播的代碼,尤其是在6.6.0版本中新增或修改的部分,確保它們都有適當(dāng)?shù)腻e(cuò)誤處理機(jī)制。
需要我進(jìn)一步分析這個(gè)問(wèn)題的特定方面嗎?
4.5.3 查詢應(yīng)用性能監(jiān)控(APM)中數(shù)據(jù)
在cursor中輸入:幫我查詢6.6.0的性能數(shù)據(jù),并和6.5.0版本對(duì)比。請(qǐng)求cursor后生成的html結(jié)果如下:
通過(guò)結(jié)果,我們可以看出,通過(guò) MCP協(xié)議,本地?cái)?shù)據(jù)得以充分供給給 AI,成功賦予了AI訪問(wèn)本地?cái)?shù)據(jù)的能力。這使得 AI能夠深度挖掘并高效利用這些數(shù)據(jù)。
5.總結(jié)
本文對(duì) MCP 進(jìn)行了簡(jiǎn)要介紹。MCP是一種高效且通用的協(xié)議,它能讓AI安全、高效地訪問(wèn)本地?cái)?shù)據(jù)。我們以 Sentry接入MCP為例,成功實(shí)現(xiàn)了Sentry監(jiān)控服務(wù)與cursor助手的集成,達(dá)成了應(yīng)用崩潰率的智能分析以及crash問(wèn)題的詳細(xì)查詢,助力大家更好地理解 MCP 的工作模式。
希望本文能幫助讀者更好地認(rèn)識(shí) MCP 協(xié)議,熟練掌握將本地?cái)?shù)據(jù)接入AI的方法。期待這篇技術(shù)分享能對(duì)您了解和運(yùn)用 MCP有所助益。