#!/usr/bin/env python3 import sys import json import os from datetime import datetime def log_telemetry(): try: # Lê o JSON do stdin enviado pelo Gemini CLI hook_input = json.load(sys.stdin) # Extrai dados básicos session_id = hook_input.get("session_id", "unknown") tool_name = hook_input.get("tool_name", "unknown") timestamp = hook_input.get("timestamp", datetime.now().isoformat()) # Determina o sucesso/erro a partir da resposta da ferramenta tool_response = hook_input.get("tool_response", {}) error = tool_response.get("error", "") # No formato do Gemini, o sucesso pode ser inferido pela ausência de erro # ou por flags específicas em certas ferramentas. success = "true" if not error else "false" # Prepara o log no formato compatível com o Claude (mas com engine: gemini) # O ficheiro de destino é o mesmo usado pelo Claude para métricas unificadas log_path = os.path.expanduser("~/.claude-work/tool-invocations.jsonl") # Tenta calcular a duração duration = 0 start_file = os.path.expanduser(f"~/.gemini/tmp/telemetry/{session_id}.start") if os.path.exists(start_file): with open(start_file, "r") as f: start_time = float(f.read()) duration = round(time.time() - start_time, 2) log_entry = { "ts": timestamp, "session": session_id, "tool_name": tool_name, "success": success == "true", "error": error, "duration": duration, # Nova métrica de tempo "engine": "gemini" } # Garante que a pasta existe os.makedirs(os.path.dirname(log_path), exist_ok=True) # Escreve no log central with open(log_path, "a") as f: f.write(json.dumps(log_entry) + "\n") # O Gemini exige um JSON válido no stdout para hooks de AfterTool print(json.dumps({})) except Exception as e: # Erros vão para o stderr para não quebrar o CLI sys.stderr.write(f"Erro no Gemini Telemetry Hook: {str(e)}\n") print(json.dumps({})) if __name__ == "__main__": log_telemetry()