| 
									
										
										
										
											2024-08-06 11:41:08 +02:00
										 |  |  | package models | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2025-02-17 16:54:25 +01:00
										 |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2024-08-06 11:41:08 +02:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/acarl005/stripansi" | 
					
						
							| 
									
										
										
										
											2025-02-17 16:54:25 +01:00
										 |  |  | 	"github.com/rs/zerolog" | 
					
						
							| 
									
										
										
										
											2024-08-06 11:41:08 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-08 17:23:01 +02:00
										 |  |  | // An object to monitor the logs generated by a specific pod from a workflow execution | 
					
						
							| 
									
										
										
										
											2024-08-06 11:41:08 +02:00
										 |  |  | type ArgoWatch struct { | 
					
						
							| 
									
										
										
										
											2024-08-19 11:43:40 +02:00
										 |  |  | 	Name      string | 
					
						
							|  |  |  | 	Namespace string | 
					
						
							|  |  |  | 	Status    string | 
					
						
							| 
									
										
										
										
											2024-08-06 11:41:08 +02:00
										 |  |  | 	Conditions | 
					
						
							| 
									
										
										
										
											2024-08-19 11:43:40 +02:00
										 |  |  | 	Created  string | 
					
						
							|  |  |  | 	Started  string | 
					
						
							|  |  |  | 	Duration string | 
					
						
							|  |  |  | 	Progress string | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | 	Logs     []string | 
					
						
							| 
									
										
										
										
											2024-08-06 11:41:08 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-19 11:43:40 +02:00
										 |  |  | type Conditions struct { | 
					
						
							|  |  |  | 	PodRunning bool | 
					
						
							|  |  |  | 	Completed  bool | 
					
						
							| 
									
										
										
										
											2024-08-06 11:41:08 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | func (a *ArgoWatch) Equals(arg *ArgoWatch) bool { | 
					
						
							|  |  |  | 	if arg == nil { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:41:08 +02:00
										 |  |  | 	return a.Status == arg.Status && a.Progress == arg.Progress && a.Conditions.PodRunning == arg.Conditions.PodRunning && a.Conditions.Completed == arg.Conditions.Completed | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | func NewArgoLogs(name string, namespace string, stepMax int) *ArgoLogs { | 
					
						
							|  |  |  | 	return &ArgoLogs{ | 
					
						
							|  |  |  | 		Name:        "oc-monitor-" + name, | 
					
						
							|  |  |  | 		Namespace:   namespace, | 
					
						
							|  |  |  | 		CreatedDate: time.Now().Format("2006-01-02 15:04:05"), | 
					
						
							|  |  |  | 		StepCount:   0, | 
					
						
							|  |  |  | 		StepMax:     stepMax, | 
					
						
							|  |  |  | 		stop:        false, | 
					
						
							| 
									
										
										
										
											2025-02-17 16:54:25 +01:00
										 |  |  | 		Seen:        []string{}, | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-08 17:23:01 +02:00
										 |  |  | // An object to monitor and log the output of an argo submit  | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | type ArgoLogs struct { | 
					
						
							|  |  |  | 	Name        string | 
					
						
							|  |  |  | 	Namespace   string | 
					
						
							|  |  |  | 	CreatedDate string | 
					
						
							|  |  |  | 	StepCount   int | 
					
						
							|  |  |  | 	StepMax     int | 
					
						
							|  |  |  | 	stop        bool | 
					
						
							|  |  |  | 	Started     time.Time | 
					
						
							| 
									
										
										
										
											2025-02-17 16:54:25 +01:00
										 |  |  | 	Seen        []string | 
					
						
							|  |  |  | 	Logs        []string | 
					
						
							|  |  |  | 	IsStreaming bool | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 16:54:25 +01:00
										 |  |  | func (a *ArgoLogs) NewWatch() *ArgoWatch { | 
					
						
							|  |  |  | 	return &ArgoWatch{ | 
					
						
							|  |  |  | 		Name:      a.Name, | 
					
						
							|  |  |  | 		Namespace: a.Namespace, | 
					
						
							|  |  |  | 		Status:    "Pending", | 
					
						
							|  |  |  | 		Created:   a.CreatedDate, | 
					
						
							|  |  |  | 		Started:   a.Started.Format("2006-01-02 15:04:05"), | 
					
						
							|  |  |  | 		Conditions: Conditions{ | 
					
						
							|  |  |  | 			PodRunning: a.StepCount > 0 && a.StepCount < a.StepMax, | 
					
						
							|  |  |  | 			Completed:  a.StepCount == a.StepMax, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		Progress: fmt.Sprintf("%v/%v", a.StepCount, a.StepMax), | 
					
						
							|  |  |  | 		Duration: "0s", | 
					
						
							|  |  |  | 		Logs:     []string{}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (a *ArgoLogs) StartStepRecording(current_watch *ArgoWatch, logger zerolog.Logger) { | 
					
						
							|  |  |  | 	jsonified, _ := json.Marshal(current_watch) | 
					
						
							|  |  |  | 	logger.Info().Msg(string(jsonified)) | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | 	a.StepCount += 1 | 
					
						
							|  |  |  | 	a.Started = time.Now() | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-08-19 11:43:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 16:54:25 +01:00
										 |  |  | func (a *ArgoLogs) StopStepRecording(current *ArgoWatch) *ArgoWatch { | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | 	fn := strings.Split(a.Name, "_") | 
					
						
							|  |  |  | 	logs := []string{} | 
					
						
							|  |  |  | 	err := false | 
					
						
							|  |  |  | 	end := "" | 
					
						
							| 
									
										
										
										
											2025-02-17 16:54:25 +01:00
										 |  |  | 	for _, input := range current.Logs { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:41:08 +02:00
										 |  |  | 		line := strings.TrimSpace(input) | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | 		if line == "" || !strings.Contains(line, fn[0]) || !strings.Contains(line, ":") { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:41:08 +02:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | 		step := strings.Split(line, ":") | 
					
						
							|  |  |  | 		if strings.Contains(line, "sub-process exited") { | 
					
						
							|  |  |  | 			b := strings.Split(line, "time=\"") | 
					
						
							|  |  |  | 			if len(b) > 1 { | 
					
						
							|  |  |  | 				end = b[1][:19] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if len(step) < 2 || strings.Contains(line, "time=") || strings.TrimSpace(strings.Join(step[1:], " : ")) == "" || strings.TrimSpace(strings.Join(step[1:], " : ")) == a.Name { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		log := stripansi.Strip(strings.TrimSpace(strings.Join(step[1:], " : "))) | 
					
						
							|  |  |  | 		t, e := strconv.Unquote(log) | 
					
						
							|  |  |  | 		if e == nil { | 
					
						
							|  |  |  | 			logs = append(logs, t) | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			logs = append(logs, strings.ReplaceAll(log, "\"", "`")) | 
					
						
							| 
									
										
										
										
											2024-08-06 11:41:08 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | 		if strings.Contains(logs[len(logs)-1], "Error") { | 
					
						
							|  |  |  | 			err = true | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:41:08 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | 	status := "Pending" | 
					
						
							|  |  |  | 	if a.StepCount > 0 { | 
					
						
							|  |  |  | 		status = "Running" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if a.StepCount == a.StepMax { | 
					
						
							|  |  |  | 		if err { | 
					
						
							|  |  |  | 			status = "Failed" | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			status = "Succeeded" | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	duration := float64(0) | 
					
						
							|  |  |  | 	if end != "" { | 
					
						
							|  |  |  | 		timeE, _ := time.Parse("2006-01-02T15:04:05", end) | 
					
						
							|  |  |  | 		duration = timeE.Sub(a.Started).Seconds() | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-02-17 16:54:25 +01:00
										 |  |  | 	current.Conditions = Conditions{ | 
					
						
							|  |  |  | 		PodRunning: a.StepCount > 0 && a.StepCount < a.StepMax, | 
					
						
							|  |  |  | 		Completed:  a.StepCount == a.StepMax, | 
					
						
							| 
									
										
										
										
											2024-10-11 13:44:16 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-02-17 16:54:25 +01:00
										 |  |  | 	current.Progress = fmt.Sprintf("%v/%v", a.StepCount, a.StepMax) | 
					
						
							|  |  |  | 	current.Duration = fmt.Sprintf("%v", fmt.Sprintf("%.2f", duration)+"s") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	current.Status = status | 
					
						
							|  |  |  | 	return current | 
					
						
							| 
									
										
										
										
											2024-08-19 11:43:40 +02:00
										 |  |  | } |