1
- use anyhow:: { Context , Ok , Result } ;
1
+ use anyhow:: { Context , Result } ;
2
2
3
3
mod args;
4
- use args:: { Args , Subcommands , actions, claude} ;
4
+ use args:: { Args , CommandName , Subcommands , actions, claude} ;
5
5
use but_settings:: AppSettings ;
6
+ use metrics:: { Event , Metrics , Props , metrics_if_configured} ;
6
7
mod command;
7
8
mod id;
8
9
mod log;
@@ -19,6 +20,7 @@ async fn main() -> Result<()> {
19
20
20
21
let namespace = option_env ! ( "IDENTIFIER" ) . unwrap_or ( "com.gitbutler.app" ) ;
21
22
gitbutler_secret:: secret:: set_application_namespace ( namespace) ;
23
+ let start = std:: time:: Instant :: now ( ) ;
22
24
23
25
match & args. cmd {
24
26
Subcommands :: Mcp { internal } => {
@@ -38,32 +40,70 @@ async fn main() -> Result<()> {
38
40
}
39
41
None => command:: list_actions ( & args. current_dir , args. json , 0 , 10 ) ,
40
42
} ,
43
+ Subcommands :: Metrics {
44
+ command_name,
45
+ props,
46
+ } => {
47
+ let event = & mut Event :: new ( ( * command_name) . into ( ) ) ;
48
+ if let Ok ( props) = Props :: from_json_string ( props) {
49
+ props. update_event ( event) ;
50
+ }
51
+ Metrics :: capture_blocking ( & app_settings, event. clone ( ) ) . await ;
52
+ Ok ( ( ) )
53
+ }
41
54
Subcommands :: Claude ( claude:: Platform { cmd } ) => match cmd {
42
55
claude:: Subcommands :: PreTool => {
43
- let out = command:: claude:: handle_pre_tool_call ( ) ?;
44
- println ! ( "{}" , serde_json:: to_string( & out) ?) ;
56
+ let result = command:: claude:: handle_pre_tool_call ( ) ;
57
+ let p = props ( start, & result) ;
58
+ println ! ( "{}" , serde_json:: to_string( & result?) ?) ;
59
+ metrics_if_configured ( app_settings, CommandName :: ClaudePreTool , p) . ok ( ) ;
45
60
Ok ( ( ) )
46
61
}
47
62
claude:: Subcommands :: PostTool => {
48
- let out = command:: claude:: handle_post_tool_call ( ) ?;
49
- println ! ( "{}" , serde_json:: to_string( & out) ?) ;
63
+ let result = command:: claude:: handle_post_tool_call ( ) ;
64
+ let p = props ( start, & result) ;
65
+ println ! ( "{}" , serde_json:: to_string( & result?) ?) ;
66
+ metrics_if_configured ( app_settings, CommandName :: ClaudePostTool , p) . ok ( ) ;
50
67
Ok ( ( ) )
51
68
}
52
69
claude:: Subcommands :: Stop => {
53
- let out = command:: claude:: handle_stop ( ) . await ?;
54
- println ! ( "{}" , serde_json:: to_string( & out) ?) ;
70
+ let result = command:: claude:: handle_stop ( ) . await ;
71
+ let p = props ( start, & result) ;
72
+ println ! ( "{}" , serde_json:: to_string( & result?) ?) ;
73
+ metrics_if_configured ( app_settings, CommandName :: ClaudeStop , p) . ok ( ) ;
55
74
Ok ( ( ) )
56
75
}
57
76
} ,
58
- Subcommands :: Log => log:: commit_graph ( & args. current_dir , args. json ) ,
59
- Subcommands :: Status => status:: worktree ( & args. current_dir , args. json ) ,
77
+ Subcommands :: Log => {
78
+ let result = log:: commit_graph ( & args. current_dir , args. json ) ;
79
+ metrics_if_configured ( app_settings, CommandName :: Log , props ( start, & result) ) . ok ( ) ;
80
+ Ok ( ( ) )
81
+ }
82
+ Subcommands :: Status => {
83
+ let result = status:: worktree ( & args. current_dir , args. json ) ;
84
+ metrics_if_configured ( app_settings, CommandName :: Status , props ( start, & result) ) . ok ( ) ;
85
+ Ok ( ( ) )
86
+ }
60
87
Subcommands :: Rub { source, target } => {
61
88
let result = rub:: handle ( & args. current_dir , args. json , source, target)
62
89
. context ( "Rubbed the wrong way." ) ;
63
90
if let Err ( e) = & result {
64
91
eprintln ! ( "{} {}" , e, e. root_cause( ) ) ;
65
92
}
93
+ metrics_if_configured ( app_settings, CommandName :: Rub , props ( start, & result) ) . ok ( ) ;
66
94
Ok ( ( ) )
67
95
}
68
96
}
69
97
}
98
+
99
+ fn props < E , T , R > ( start : std:: time:: Instant , result : R ) -> Props
100
+ where
101
+ R : std:: ops:: Deref < Target = Result < T , E > > ,
102
+ E : std:: fmt:: Display ,
103
+ {
104
+ let error = result. as_ref ( ) . err ( ) . map ( |e| e. to_string ( ) ) ;
105
+ let mut props = Props :: new ( ) ;
106
+ props. insert ( "durationMs" , start. elapsed ( ) . as_millis ( ) ) ;
107
+ props. insert ( "error" , error) ;
108
+ props
109
+ }
0 commit comments