-
Notifications
You must be signed in to change notification settings - Fork 54
/
app_logs.go
94 lines (77 loc) · 2.73 KB
/
app_logs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package actions
import (
"context"
"errors"
"sort"
"code.cloudfoundry.org/korifi/api/actions/shared"
"code.cloudfoundry.org/korifi/api/authorization"
apierrors "code.cloudfoundry.org/korifi/api/errors"
"code.cloudfoundry.org/korifi/api/payloads"
"code.cloudfoundry.org/korifi/api/repositories"
"github.com/go-logr/logr"
)
type AppLogs struct {
appRepo shared.CFAppRepository
buildRepo shared.CFBuildRepository
podRepo shared.PodRepository
}
func NewAppLogs(appRepo shared.CFAppRepository, buildRepo shared.CFBuildRepository, podRepo shared.PodRepository) *AppLogs {
return &AppLogs{
appRepo: appRepo,
buildRepo: buildRepo,
podRepo: podRepo,
}
}
func (a *AppLogs) Read(ctx context.Context, logger logr.Logger, authInfo authorization.Info, appGUID string, read payloads.LogRead) ([]repositories.LogRecord, error) {
const (
defaultLogLimit = 100
)
app, err := a.appRepo.GetApp(ctx, authInfo, appGUID)
if err != nil {
return nil, apierrors.LogAndReturn(logger, apierrors.ForbiddenAsNotFound(err), "Failed to fetch app from Kubernetes", "AppGUID", appGUID)
}
build, err := a.buildRepo.GetLatestBuildByAppGUID(ctx, authInfo, app.SpaceGUID, appGUID)
if err != nil {
if !errors.As(err, new(apierrors.NotFoundError)) {
return nil, apierrors.LogAndReturn(logger, apierrors.ForbiddenAsNotFound(err), "Failed to fetch latest app CFBuild from Kubernetes", "AppGUID", appGUID)
}
return []repositories.LogRecord{}, nil
}
buildLogs, err := a.buildRepo.GetBuildLogs(ctx, authInfo, app.SpaceGUID, build.GUID)
if err != nil {
return nil, apierrors.LogAndReturn(logger, err, "Failed to fetch build logs", "AppGUID", appGUID, "BuildGUID", build.GUID)
}
logLimit := int64(defaultLogLimit)
if read.Limit != 0 {
logLimit = read.Limit
}
runtimeLogs, err := a.podRepo.GetRuntimeLogsForApp(ctx, logger, authInfo, repositories.RuntimeLogsMessage{
SpaceGUID: app.SpaceGUID,
AppGUID: app.GUID,
AppRevision: app.Revision,
Limit: logLimit,
})
if err != nil {
return nil, apierrors.LogAndReturn(logger, err, "Failed to fetch app runtime logs from Kubernetes", "AppGUID", appGUID)
}
logs := append(buildLogs, runtimeLogs...)
sort.Slice(logs, func(i, j int) bool {
return logs[i].Timestamp < logs[j].Timestamp
})
// ensure that we didn't exceed the log limit
if read.Limit != 0 && int64(len(logs)) > read.Limit {
first := int64(len(logs)) - read.Limit
logs = logs[first:]
}
// filter any entries from before the start time
if read.StartTime != 0 {
first := sort.Search(len(logs), func(i int) bool { return read.StartTime <= logs[i].Timestamp })
logs = logs[first:]
}
if read.Descending {
for i, j := 0, len(logs)-1; i < j; i, j = i+1, j-1 {
logs[i], logs[j] = logs[j], logs[i]
}
}
return logs, nil
}