feat(mcp): helper track_mcp_tool pour tracer les appels MCP dans Matomo
This commit is contained in:
@@ -28,3 +28,35 @@ def track_search(query, category):
|
|||||||
url=f"https://{os.getenv('MATOMO_DOMAIN')}/matomo.php",
|
url=f"https://{os.getenv('MATOMO_DOMAIN')}/matomo.php",
|
||||||
params=params,
|
params=params,
|
||||||
).raise_for_status()
|
).raise_for_status()
|
||||||
|
|
||||||
|
|
||||||
|
def track_mcp_tool(tool_name: str, query: str | None = None) -> None:
|
||||||
|
"""Enregistre un appel d'outil MCP dans Matomo (best-effort, prod uniquement).
|
||||||
|
|
||||||
|
`action_name="MCP / <tool>"`, `dimension1=<tool>`. Si l'outil porte une
|
||||||
|
requête texte, elle est envoyée en `search`. Nécessite un Custom Dimension
|
||||||
|
slot 1 (scope Action) configuré côté Matomo — sinon `dimension1` est ignoré.
|
||||||
|
Ne lève jamais : une panne Matomo ne doit pas casser l'appel du tool.
|
||||||
|
"""
|
||||||
|
if DEVELOPMENT or not os.getenv("MATOMO_DOMAIN"):
|
||||||
|
return
|
||||||
|
params = {
|
||||||
|
"idsite": os.getenv("MATOMO_ID_SITE"),
|
||||||
|
"url": "https://colibre.fr/_mcp",
|
||||||
|
"rec": "1",
|
||||||
|
"action_name": f"MCP / {tool_name}",
|
||||||
|
"dimension1": tool_name,
|
||||||
|
"rand": uuid.uuid4().hex,
|
||||||
|
"apiv": "1",
|
||||||
|
"h": localtime().tm_hour,
|
||||||
|
"m": localtime().tm_min,
|
||||||
|
"s": localtime().tm_sec,
|
||||||
|
"token_auth": os.getenv("MATOMO_TOKEN"),
|
||||||
|
}
|
||||||
|
if query:
|
||||||
|
params["search"] = query
|
||||||
|
params["search_cat"] = "mcp"
|
||||||
|
try:
|
||||||
|
post(url=f"https://{os.getenv('MATOMO_DOMAIN')}/matomo.php", params=params)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import src.utils.tracking as tracking
|
||||||
|
|
||||||
|
|
||||||
|
def test_track_mcp_tool_sends_action_and_dimension(monkeypatch):
|
||||||
|
captured = {}
|
||||||
|
|
||||||
|
def fake_post(url, params):
|
||||||
|
captured["url"] = url
|
||||||
|
captured["params"] = params
|
||||||
|
|
||||||
|
class _R:
|
||||||
|
def raise_for_status(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
return _R()
|
||||||
|
|
||||||
|
monkeypatch.setattr(tracking, "DEVELOPMENT", False)
|
||||||
|
monkeypatch.setattr(tracking, "post", fake_post)
|
||||||
|
monkeypatch.setenv("MATOMO_DOMAIN", "matomo.example")
|
||||||
|
monkeypatch.setenv("MATOMO_ID_SITE", "1")
|
||||||
|
|
||||||
|
tracking.track_mcp_tool("rechercher_marches", query="informatique")
|
||||||
|
|
||||||
|
assert captured["params"]["action_name"] == "MCP / rechercher_marches"
|
||||||
|
assert captured["params"]["dimension1"] == "rechercher_marches"
|
||||||
|
assert captured["params"]["search"] == "informatique"
|
||||||
|
|
||||||
|
|
||||||
|
def test_track_mcp_tool_noop_in_development(monkeypatch):
|
||||||
|
called = False
|
||||||
|
|
||||||
|
def fake_post(url, params):
|
||||||
|
nonlocal called
|
||||||
|
called = True
|
||||||
|
|
||||||
|
monkeypatch.setattr(tracking, "DEVELOPMENT", True)
|
||||||
|
monkeypatch.setattr(tracking, "post", fake_post)
|
||||||
|
monkeypatch.setenv("MATOMO_DOMAIN", "matomo.example")
|
||||||
|
|
||||||
|
tracking.track_mcp_tool("stats_acheteur")
|
||||||
|
|
||||||
|
assert called is False
|
||||||
Reference in New Issue
Block a user