Instrument the SMTP code using runtime/trace

runtime/trace together with 'go tool trace' provides extremely powerful
tooling for performance (latency) analysis. Since maddy prides itself on
being "optimized for concurrency", it is a good idea to actually live up
to this promise.

Closes #144. No need to reinvent the wheel. The original issue
proposed a solution to use in production to detect "performance
anomalies", it is possible to use runtime/trace in production too, but
the corresponding flag to enable profiler endpoint is hidden behind the
'debugflags' build tag at the moment.

For SMTP code, the basic latency information can be obtained from
regular logs since they include timestamps with millisecond granularity.
After the issue is apparent, it is possible to deploy the server
executable compiled with tracing support and obtain more information

... Also add missing context.Context arguments to smtpconn.C.
This commit is contained in:
fox.cpp 2019-12-09 23:11:39 +03:00
parent 305fdddf24
commit c4ea9a730f
No known key found for this signature in database
GPG key ID: E76D97CCEDE90B6C
20 changed files with 281 additions and 135 deletions

View file

@ -11,6 +11,7 @@ import (
"os"
"os/exec"
"regexp"
"runtime/trace"
"strconv"
"strings"
@ -300,6 +301,9 @@ func (s *state) CheckConnection(ctx context.Context) module.CheckResult {
return module.CheckResult{}
}
// TODO: It is not possible to distinguish different commands.
defer trace.StartRegion(ctx, "command/CheckConnection").End()
cmdName, cmdArgs := s.expandCommand("")
return s.run(cmdName, cmdArgs, bytes.NewReader(nil))
}
@ -311,6 +315,8 @@ func (s *state) CheckSender(ctx context.Context, addr string) module.CheckResult
return module.CheckResult{}
}
defer trace.StartRegion(ctx, "command/CheckSender").End()
cmdName, cmdArgs := s.expandCommand(addr)
return s.run(cmdName, cmdArgs, bytes.NewReader(nil))
}
@ -321,6 +327,7 @@ func (s *state) CheckRcpt(ctx context.Context, addr string) module.CheckResult {
if s.c.stage != StageRcpt {
return module.CheckResult{}
}
defer trace.StartRegion(ctx, "command/CheckRcpt").End()
cmdName, cmdArgs := s.expandCommand(addr)
return s.run(cmdName, cmdArgs, bytes.NewReader(nil))
@ -331,6 +338,8 @@ func (s *state) CheckBody(ctx context.Context, hdr textproto.Header, body buffer
return module.CheckResult{}
}
defer trace.StartRegion(ctx, "command/CheckBody").End()
cmdName, cmdArgs := s.expandCommand("")
var buf bytes.Buffer