Improve wf debugging capabilities (session tracing)

This commit is contained in:
Denis Arh
2021-04-14 17:24:25 +02:00
parent 5ce2ac9767
commit a4633f5677
2 changed files with 26 additions and 18 deletions
+16 -17
View File
@@ -179,14 +179,9 @@ func (svc *session) Start(g *wfexec.Graph, i auth.Identifiable, ssp types.Sessio
ses.CreatedAt = *now()
ses.CreatedBy = i.Identity()
ses.Status = types.SessionStarted
ses.Apply(ssp)
if ssp.Trace {
if err = store.CreateAutomationSession(context.TODO(), svc.store, ses); err != nil {
return
}
}
if err = ses.Exec(ctx, start, ssp.Input); err != nil {
return
}
@@ -344,21 +339,20 @@ func (svc *session) stateChangeHandler(ctx context.Context) wfexec.StateChangeHa
var (
// By default we want to update session when new status is prompted, delayed, completed or failed
//
// But if status is active, we
// But if status is active, we'll flush it every X frames (flushFrquency)
update = true
frame = state.MakeFrame()
frame = state.MakeFrame()
)
// Stacktrace will be set to !nil if frame collection is needed
if ses.Stacktrace != nil {
if len(ses.Stacktrace) > 0 {
// calculate how long it took to get to this step
frame.ElapsedTime = uint(frame.CreatedAt.Sub(ses.Stacktrace[0].CreatedAt) / time.Millisecond)
}
ses.Stacktrace = append(ses.Stacktrace, frame)
if len(ses.RuntimeStacktrace) > 0 {
// calculate how long it took to get to this step
frame.ElapsedTime = uint(frame.CreatedAt.Sub(ses.RuntimeStacktrace[0].CreatedAt) / time.Millisecond)
}
ses.RuntimeStacktrace = append(ses.RuntimeStacktrace, frame)
switch i {
case wfexec.SessionPrompted:
ses.SuspendedAt = now()
@@ -381,14 +375,19 @@ func (svc *session) stateChangeHandler(ctx context.Context) wfexec.StateChangeHa
default:
// force update on every 10 new frames but only when stacktrace is not nil
update = ses.Stacktrace != nil && len(ses.Stacktrace)%flushFrequency == 0
update = ses.RuntimeStacktrace != nil && len(ses.RuntimeStacktrace)%flushFrequency == 0
}
if !update {
return
}
if err := svc.store.UpdateAutomationSession(ctx, ses); err != nil {
if ses.Stacktrace != nil || ses.Error != "" {
// Save stacktrace when we know we're tracing workflows OR whenever there is an error...
ses.Stacktrace = ses.RuntimeStacktrace
}
if err := svc.store.UpsertAutomationSession(ctx, ses); err != nil {
log.Error("failed to update session", zap.Error(err))
} else {
log.Debug("session updated", zap.Stringer("status", ses.Status))
+10 -1
View File
@@ -25,6 +25,7 @@ type (
Input *expr.Vars `json:"input"`
Output *expr.Vars `json:"output"`
// Stacktrace that gets stored (if/when configured)
Stacktrace Stacktrace `json:"stacktrace"`
CreatedAt time.Time `json:"createdAt,omitempty"`
@@ -38,6 +39,13 @@ type (
Error string `json:"error,omitempty"`
session *wfexec.Session
// For keeping runtime stacktrace,
// even if we do not want to store it on every update
//
// This will aid us when session fails and we can access
// the whole stacktrace
RuntimeStacktrace Stacktrace `json:"-"`
}
SessionStartParams struct {
@@ -124,7 +132,8 @@ func (s *Session) Apply(ssp SessionStartParams) {
}
if ssp.Trace {
// set prop
// set Stacktrace prop to signal status handler
// that we're interested in storing stacktrace
s.Stacktrace = Stacktrace{}
}
}