From 294ad89a194a2572c2980dbaf2ef39f47ceb4ffe Mon Sep 17 00:00:00 2001 From: Amir Raminfar Date: Fri, 3 Jan 2025 06:50:01 -0800 Subject: [PATCH 1/6] wip finished --- internal/docker/client.go | 8 ++++++-- internal/docker/types.go | 28 +++++++++++++++------------- internal/web/logs.go | 11 ++++++++++- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/internal/docker/client.go b/internal/docker/client.go index 974ab8619aab..9f6f8a5c5045 100644 --- a/internal/docker/client.go +++ b/internal/docker/client.go @@ -385,12 +385,16 @@ func newContainerFromJSON(c types.ContainerJSON, host string) Container { Tty: c.Config.Tty, } + if createdAt, err := time.Parse(time.RFC3339Nano, c.Created); err == nil { + container.Created = createdAt.UTC() + } + if startedAt, err := time.Parse(time.RFC3339Nano, c.State.StartedAt); err == nil { container.StartedAt = startedAt.UTC() } - if createdAt, err := time.Parse(time.RFC3339Nano, c.Created); err == nil { - container.Created = createdAt.UTC() + if stoppedAt, err := time.Parse(time.RFC3339Nano, c.State.FinishedAt); err == nil { + container.FinishedAt = stoppedAt.UTC() } if c.State.Health != nil { diff --git a/internal/docker/types.go b/internal/docker/types.go index 345729563c3e..962199a628fd 100644 --- a/internal/docker/types.go +++ b/internal/docker/types.go @@ -12,19 +12,20 @@ import ( // Container represents an internal representation of docker containers type Container struct { - ID string `json:"id"` - Name string `json:"name"` - Image string `json:"image"` - Command string `json:"command"` - Created time.Time `json:"created"` - StartedAt time.Time `json:"startedAt,omitempty"` - State string `json:"state"` - Health string `json:"health,omitempty"` - Host string `json:"host,omitempty"` - Tty bool `json:"-"` - Labels map[string]string `json:"labels,omitempty"` - Stats *utils.RingBuffer[ContainerStat] `json:"stats,omitempty"` - Group string `json:"group,omitempty"` + ID string `json:"id"` + Name string `json:"name"` + Image string `json:"image"` + Command string `json:"command"` + Created time.Time `json:"created"` + StartedAt time.Time `json:"startedAt"` + FinishedAt time.Time `json:"finishedAt"` + State string `json:"state"` + Health string `json:"health,omitempty"` + Host string `json:"host,omitempty"` + Tty bool `json:"-"` + Labels map[string]string `json:"labels,omitempty"` + Stats *utils.RingBuffer[ContainerStat] `json:"stats,omitempty"` + Group string `json:"group,omitempty"` } // ContainerStat represent stats instant for a container @@ -41,6 +42,7 @@ type ContainerEvent struct { Host string `json:"host"` ActorID string `json:"actorId"` ActorAttributes map[string]string `json:"actorAttributes,omitempty"` + Time time.Time `json:"time"` } type ContainerFilter map[string][]string diff --git a/internal/web/logs.go b/internal/web/logs.go index d9b774009de3..e4c4b630402a 100644 --- a/internal/web/logs.go +++ b/internal/web/logs.go @@ -347,7 +347,16 @@ func (h *handler) streamLogsForContainers(w http.ResponseWriter, r *http.Request if err != nil { if errors.Is(err, io.EOF) { log.Debug().Str("container", container.ID).Msg("streaming ended") - events <- &docker.ContainerEvent{ActorID: container.ID, Name: "container-stopped", Host: container.Host} + finishedAt := container.FinishedAt + if container.FinishedAt.IsZero() { + finishedAt = time.Now() + } + events <- &docker.ContainerEvent{ + ActorID: container.ID, + Name: "container-stopped", + Host: container.Host, + Time: finishedAt, + } } else if !errors.Is(err, context.Canceled) { log.Error().Err(err).Str("container", container.ID).Msg("unknown error while streaming logs") } From 5ad0747e8568e62420e9106debd3dae3f60c4310 Mon Sep 17 00:00:00 2001 From: Amir Raminfar Date: Fri, 3 Jan 2025 10:45:04 -0800 Subject: [PATCH 2/6] feat: handles container exit and finished at --- assets/components/ContainerPopup.vue | 18 ++++++++++++++---- assets/components/HostMenu.vue | 2 +- assets/composable/eventStreams.ts | 3 ++- assets/models/Container.ts | 2 ++ assets/stores/container.ts | 16 +++++++++++++++- assets/types/Container.d.ts | 4 +++- internal/docker/container_store.go | 28 ++++++++++++++++++++++++++++ internal/web/events.go | 8 ++++++++ internal/web/logs.go | 1 + vite.config.ts | 10 +++++----- 10 files changed, 79 insertions(+), 13 deletions(-) diff --git a/assets/components/ContainerPopup.vue b/assets/components/ContainerPopup.vue index c65d07058da8..5ba3836797dc 100644 --- a/assets/components/ContainerPopup.vue +++ b/assets/components/ContainerPopup.vue @@ -1,15 +1,25 @@