@@ -201,8 +201,7 @@ func (s *Server) sessionHandler(session ssh.Session) {
201
201
return
202
202
}
203
203
204
- m := metricsForSession (s .metrics .sessions , magicType (session ))
205
- err := s .sessionStart (session , m , extraEnv )
204
+ err := s .sessionStart (session , extraEnv )
206
205
var exitError * exec.ExitError
207
206
if xerrors .As (err , & exitError ) {
208
207
s .logger .Warn (ctx , "ssh session returned" , slog .Error (exitError ))
@@ -229,7 +228,7 @@ func magicType(session ssh.Session) string {
229
228
return ""
230
229
}
231
230
232
- func (s * Server ) sessionStart (session ssh.Session , m sessionMetricsObject , extraEnv []string ) (retErr error ) {
231
+ func (s * Server ) sessionStart (session ssh.Session , extraEnv []string ) (retErr error ) {
233
232
ctx := session .Context ()
234
233
env := append (session .Environ (), extraEnv ... )
235
234
var magicType string
@@ -254,16 +253,18 @@ func (s *Server) sessionStart(session ssh.Session, m sessionMetricsObject, extra
254
253
s .logger .Warn (ctx , "invalid magic ssh session type specified" , slog .F ("type" , magicType ))
255
254
}
256
255
256
+ magicTypeLabel := magicTypeMetricLabel (magicType )
257
+
257
258
cmd , err := s .CreateCommand (ctx , session .RawCommand (), env )
258
259
if err != nil {
259
- m . agentCreateCommandError .Add (1 )
260
+ s . metrics . sessionErrors . WithLabelValues ( magicTypeLabel , "create_command" ) .Add (1 )
260
261
return err
261
262
}
262
263
263
264
if ssh .AgentRequested (session ) {
264
265
l , err := ssh .NewAgentListener ()
265
266
if err != nil {
266
- m . agentListenerError .Add (1 )
267
+ s . metrics . sessionErrors . WithLabelValues ( magicTypeLabel , "listener" ) .Add (1 )
267
268
return xerrors .Errorf ("new agent listener: %w" , err )
268
269
}
269
270
defer l .Close ()
@@ -273,33 +274,33 @@ func (s *Server) sessionStart(session ssh.Session, m sessionMetricsObject, extra
273
274
274
275
sshPty , windowSize , isPty := session .Pty ()
275
276
if isPty {
276
- return s .startPTYSession (session , m , cmd , sshPty , windowSize )
277
+ return s .startPTYSession (session , magicTypeLabel , cmd , sshPty , windowSize )
277
278
}
278
- return startNonPTYSession (session , m , cmd .AsExec ())
279
+ return s . startNonPTYSession (session , magicTypeLabel , cmd .AsExec ())
279
280
}
280
281
281
- func startNonPTYSession (session ssh.Session , m sessionMetricsObject , cmd * exec.Cmd ) error {
282
- m . startNonPTYSession .Add (1 )
282
+ func ( s * Server ) startNonPTYSession (session ssh.Session , magicTypeLabel string , cmd * exec.Cmd ) error {
283
+ s . metrics . sessionsTotal . WithLabelValues ( magicTypeLabel , "no" ) .Add (1 )
283
284
284
285
cmd .Stdout = session
285
286
cmd .Stderr = session .Stderr ()
286
287
// This blocks forever until stdin is received if we don't
287
288
// use StdinPipe. It's unknown what causes this.
288
289
stdinPipe , err := cmd .StdinPipe ()
289
290
if err != nil {
290
- m . nonPTYStdinPipeError .Add (1 )
291
+ s . metrics . sessionErrors . WithLabelValues ( magicTypeLabel , "no" , "stdin_pipe" ) .Add (1 )
291
292
return xerrors .Errorf ("create stdin pipe: %w" , err )
292
293
}
293
294
go func () {
294
295
_ , err := io .Copy (stdinPipe , session )
295
296
if err != nil {
296
- m . nonPTYStdinIoCopyError .Add (1 )
297
+ s . metrics . sessionErrors . WithLabelValues ( magicTypeLabel , "no" , "stdin_io_copy" ) .Add (1 )
297
298
}
298
299
_ = stdinPipe .Close ()
299
300
}()
300
301
err = cmd .Start ()
301
302
if err != nil {
302
- m . nonPTYCmdStartError .Add (1 )
303
+ s . metrics . sessionErrors . WithLabelValues ( magicTypeLabel , "no" , "start_command" ) .Add (1 )
303
304
return xerrors .Errorf ("start: %w" , err )
304
305
}
305
306
return cmd .Wait ()
@@ -314,8 +315,8 @@ type ptySession interface {
314
315
RawCommand () string
315
316
}
316
317
317
- func (s * Server ) startPTYSession (session ptySession , m sessionMetricsObject , cmd * pty.Cmd , sshPty ssh.Pty , windowSize <- chan ssh.Window ) (retErr error ) {
318
- m . startPTYSession .Add (1 )
318
+ func (s * Server ) startPTYSession (session ptySession , magicTypeLabel string , cmd * pty.Cmd , sshPty ssh.Pty , windowSize <- chan ssh.Window ) (retErr error ) {
319
+ s . metrics . sessionsTotal . WithLabelValues ( magicTypeLabel , "yes" ) .Add (1 )
319
320
320
321
ctx := session .Context ()
321
322
// Disable minimal PTY emulation set by gliderlabs/ssh (NL-to-CRNL).
@@ -328,7 +329,7 @@ func (s *Server) startPTYSession(session ptySession, m sessionMetricsObject, cmd
328
329
err := showMOTD (session , manifest .MOTDFile )
329
330
if err != nil {
330
331
s .logger .Error (ctx , "show MOTD" , slog .Error (err ))
331
- m . ptyMotdError .Add (1 )
332
+ s . metrics . sessionErrors . WithLabelValues ( magicTypeLabel , "yes" , "motd" ) .Add (1 )
332
333
}
333
334
} else {
334
335
s .logger .Warn (ctx , "metadata lookup failed, unable to show MOTD" )
@@ -343,14 +344,14 @@ func (s *Server) startPTYSession(session ptySession, m sessionMetricsObject, cmd
343
344
pty .WithLogger (slog .Stdlib (ctx , s .logger , slog .LevelInfo )),
344
345
))
345
346
if err != nil {
346
- m . ptyCmdStartError .Add (1 )
347
+ s . metrics . sessionErrors . WithLabelValues ( magicTypeLabel , "yes" , "start_command" ) .Add (1 )
347
348
return xerrors .Errorf ("start command: %w" , err )
348
349
}
349
350
defer func () {
350
351
closeErr := ptty .Close ()
351
352
if closeErr != nil {
352
353
s .logger .Warn (ctx , "failed to close tty" , slog .Error (closeErr ))
353
- m . ptyCloseError .Add (1 )
354
+ s . metrics . sessionErrors . WithLabelValues ( magicTypeLabel , "yes" , "close" ) .Add (1 )
354
355
if retErr == nil {
355
356
retErr = closeErr
356
357
}
@@ -362,15 +363,15 @@ func (s *Server) startPTYSession(session ptySession, m sessionMetricsObject, cmd
362
363
// If the pty is closed, then command has exited, no need to log.
363
364
if resizeErr != nil && ! errors .Is (resizeErr , pty .ErrClosed ) {
364
365
s .logger .Warn (ctx , "failed to resize tty" , slog .Error (resizeErr ))
365
- m . ptyResizeError .Add (1 )
366
+ s . metrics . sessionErrors . WithLabelValues ( magicTypeLabel , "yes" , "resize" ) .Add (1 )
366
367
}
367
368
}
368
369
}()
369
370
370
371
go func () {
371
372
_ , err := io .Copy (ptty .InputWriter (), session )
372
373
if err != nil {
373
- m . ptyInputIoCopyError .Add (1 )
374
+ s . metrics . sessionErrors . WithLabelValues ( magicTypeLabel , "yes" , "input_io_copy" ) .Add (1 )
374
375
}
375
376
}()
376
377
@@ -385,7 +386,7 @@ func (s *Server) startPTYSession(session ptySession, m sessionMetricsObject, cmd
385
386
n , err := io .Copy (session , ptty .OutputReader ())
386
387
s .logger .Debug (ctx , "copy output done" , slog .F ("bytes" , n ), slog .Error (err ))
387
388
if err != nil {
388
- m . ptyOutputIoCopyError .Add (1 )
389
+ s . metrics . sessionErrors . WithLabelValues ( magicTypeLabel , "yes" , "output_io_copy" ) .Add (1 )
389
390
return xerrors .Errorf ("copy error: %w" , err )
390
391
}
391
392
// We've gotten all the output, but we need to wait for the process to
@@ -397,7 +398,7 @@ func (s *Server) startPTYSession(session ptySession, m sessionMetricsObject, cmd
397
398
// and not something to be concerned about. But, if it's something else, we should log it.
398
399
if err != nil && ! xerrors .As (err , & exitErr ) {
399
400
s .logger .Warn (ctx , "wait error" , slog .Error (err ))
400
- m . ptyWaitError .Add (1 )
401
+ s . metrics . sessionErrors . WithLabelValues ( magicTypeLabel , "yes" , "wait" ) .Add (1 )
401
402
}
402
403
if err != nil {
403
404
return xerrors .Errorf ("process wait: %w" , err )
0 commit comments