Skip to content

Commit 902d8a2

Browse files
Merge pull request #447 from AlexVulaj/show-service-logs-internal-id
Use new servicelog endpoint for listing service logs
2 parents 4679b7d + ea9e445 commit 902d8a2

File tree

8 files changed

+167
-132
lines changed

8 files changed

+167
-132
lines changed

cmd/cluster/context.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cluster
33
import (
44
"encoding/json"
55
"fmt"
6+
v1 "github.com/openshift-online/ocm-sdk-go/servicelogs/v1"
67
"os"
78
"os/exec"
89
"sort"
@@ -17,7 +18,6 @@ import (
1718
"github.com/aws/aws-sdk-go-v2/service/cloudtrail"
1819
"github.com/aws/aws-sdk-go-v2/service/cloudtrail/types"
1920
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
20-
sl "github.com/openshift/osdctl/internal/servicelog"
2121
"github.com/openshift/osdctl/pkg/osdCloud"
2222
"github.com/openshift/osdctl/pkg/osdctlConfig"
2323
"github.com/openshift/osdctl/pkg/printer"
@@ -72,7 +72,7 @@ type contextData struct {
7272
// limited Support Status
7373
LimitedSupportReasons []*cmv1.LimitedSupportReason
7474
// Service Logs
75-
ServiceLogs []sl.ServiceLogShort
75+
ServiceLogs []*v1.LogEntry
7676

7777
// Jira Cards
7878
JiraIssues []jira.Issue
@@ -263,7 +263,7 @@ func (o *contextOptions) printShortOutput(data *contextData) {
263263

264264
var numInternalServiceLogs int
265265
for _, serviceLog := range data.ServiceLogs {
266-
if serviceLog.InternalOnly {
266+
if serviceLog.InternalOnly() {
267267
numInternalServiceLogs++
268268
}
269269
}
@@ -360,7 +360,7 @@ func (o *contextOptions) generateContextData() (*contextData, []error) {
360360
if o.verbose {
361361
fmt.Fprintln(os.Stderr, "Getting Service Logs...")
362362
}
363-
data.ServiceLogs, err = servicelog.GetServiceLogsSince(cluster.ID(), o.days)
363+
data.ServiceLogs, err = servicelog.GetServiceLogsSince(cluster.ID(), o.days, false, false)
364364
if err != nil {
365365
errors = append(errors, fmt.Errorf("Error while getting the service logs: %v", err))
366366
}

cmd/org/context.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8+
v1 "github.com/openshift-online/ocm-sdk-go/servicelogs/v1"
89
"os"
910
"strconv"
1011
"sync"
@@ -14,7 +15,6 @@ import (
1415
sdk "github.com/openshift-online/ocm-sdk-go"
1516
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
1617
"github.com/openshift/osdctl/cmd/servicelog"
17-
sl "github.com/openshift/osdctl/internal/servicelog"
1818
"github.com/openshift/osdctl/pkg/printer"
1919
pdProvider "github.com/openshift/osdctl/pkg/provider/pagerduty"
2020
"github.com/openshift/osdctl/pkg/utils"
@@ -34,7 +34,7 @@ type ClusterInfo struct {
3434
CloudProvider string
3535
Plan string
3636
NodeCount float64
37-
ServiceLogs []sl.ServiceLogShort
37+
ServiceLogs []*v1.LogEntry
3838
PdAlerts map[string][]pd.Incident
3939
JiraIssues []jira.Issue
4040
LimitedSupportReasons []*cmv1.LimitedSupportReason
@@ -285,7 +285,7 @@ func addLimitedSupportReasons(clusterInfo *ClusterInfo, ocmClient *sdk.Connectio
285285

286286
func addServiceLogs(clusterInfo *ClusterInfo) error {
287287
var err error
288-
clusterInfo.ServiceLogs, err = servicelog.GetServiceLogsSince(clusterInfo.ID, ServiceLogDaysSince)
288+
clusterInfo.ServiceLogs, err = servicelog.GetServiceLogsSince(clusterInfo.ID, ServiceLogDaysSince, false, false)
289289
if err != nil {
290290
return fmt.Errorf("failed to fetch service logs for cluster %v: %w", clusterInfo.ID, err)
291291
}

cmd/servicelog/common.go

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ package servicelog
33
import (
44
"encoding/json"
55
"fmt"
6+
sdk "github.com/openshift-online/ocm-sdk-go"
7+
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
8+
v1 "github.com/openshift-online/ocm-sdk-go/servicelogs/v1"
69
"github.com/openshift/osdctl/internal/servicelog"
7-
sl "github.com/openshift/osdctl/internal/servicelog"
10+
"github.com/openshift/osdctl/pkg/utils"
811
"time"
912
)
1013

@@ -61,30 +64,72 @@ func validateBadResponse(body []byte) (badReply *servicelog.BadReply, err error)
6164
// time.Now() and time.Now()-duration. the first parameter will contain a slice
6265
// of the service logs from the given time period, while the second return value
6366
// indicates if an error has happened.
64-
func GetServiceLogsSince(clusterID string, days int) ([]sl.ServiceLogShort, error) {
67+
func GetServiceLogsSince(clusterID string, days int, allMessages bool, internalOnly bool) ([]*v1.LogEntry, error) {
6568
// time.Now().Sub() returns the duration between two times, so we negate the duration in Add()
6669
earliestTime := time.Now().AddDate(0, 0, -days)
6770

68-
slResponse, err := FetchServiceLogs(clusterID)
71+
slResponse, err := FetchServiceLogs(clusterID, allMessages, internalOnly)
6972
if err != nil {
7073
return nil, err
7174
}
7275

73-
var serviceLogs sl.ServiceLogShortList
74-
err = json.Unmarshal(slResponse.Bytes(), &serviceLogs)
76+
var errorServiceLogs []*v1.LogEntry
77+
for _, serviceLog := range slResponse.Items().Slice() {
78+
if serviceLog.CreatedAt().After(earliestTime) {
79+
errorServiceLogs = append(errorServiceLogs, serviceLog)
80+
}
81+
}
82+
83+
return errorServiceLogs, nil
84+
}
85+
86+
func FetchServiceLogs(clusterID string, allMessages bool, internalOnly bool) (*v1.ClustersClusterLogsListResponse, error) {
87+
// Create OCM client to talk to cluster API
88+
ocmClient, err := utils.CreateConnection()
7589
if err != nil {
76-
return nil, fmt.Errorf("failed to unmarshal the SL response %w", err)
90+
return nil, err
91+
}
92+
defer func() {
93+
if err := ocmClient.Close(); err != nil {
94+
fmt.Printf("Cannot close the ocmClient (possible memory leak): %q", err)
95+
}
96+
}()
7797

98+
// Use the OCM client to retrieve clusters
99+
clusters := utils.GetClusters(ocmClient, []string{clusterID})
100+
if len(clusters) != 1 {
101+
return nil, fmt.Errorf("GetClusters expected to return 1 cluster, got: %d", len(clusters))
78102
}
103+
cluster := clusters[0]
79104

80-
// Parsing the relevant service logs
81-
// - We only care about SLs sent in the given duration
82-
var errorServiceLogs []sl.ServiceLogShort
83-
for _, serviceLog := range serviceLogs.Items {
84-
if serviceLog.CreatedAt.After(earliestTime) {
85-
errorServiceLogs = append(errorServiceLogs, serviceLog)
105+
// Now get the SLs for the cluster
106+
clusterLogsListResponse, err := sendClusterLogsListRequest(ocmClient, cluster, allMessages, internalOnly)
107+
if err != nil {
108+
return nil, fmt.Errorf("failed to fetch service logs for cluster %v: %w", clusterID, err)
109+
}
110+
return clusterLogsListResponse, nil
111+
}
112+
113+
func sendClusterLogsListRequest(ocmClient *sdk.Connection, cluster *cmv1.Cluster, allMessages bool, internalMessages bool) (*v1.ClustersClusterLogsListResponse, error) {
114+
request := ocmClient.ServiceLogs().V1().Clusters().ClusterLogs().List().
115+
Parameter("cluster_id", cluster.ID()).
116+
Parameter("cluster_uuid", cluster.ExternalID())
117+
118+
var searchQuery string
119+
if !allMessages {
120+
searchQuery = "service_name='SREManualAction'"
121+
}
122+
if internalMessages {
123+
if searchQuery != "" {
124+
searchQuery += " and "
86125
}
126+
searchQuery += "internal_only='true'"
87127
}
128+
request.Search(searchQuery)
88129

89-
return errorServiceLogs, nil
130+
response, err := request.Send()
131+
if err != nil {
132+
return nil, fmt.Errorf("failed to fetch service logs: %w", err)
133+
}
134+
return response, nil
90135
}

cmd/servicelog/list.go

Lines changed: 92 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,129 @@
11
package servicelog
22

33
import (
4+
"encoding/json"
45
"fmt"
6+
slv1 "github.com/openshift-online/ocm-sdk-go/servicelogs/v1"
57
"os"
8+
"time"
69

7-
"github.com/openshift-online/ocm-cli/pkg/arguments"
810
"github.com/openshift-online/ocm-cli/pkg/dump"
9-
sdk "github.com/openshift-online/ocm-sdk-go"
10-
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
11-
"github.com/openshift/osdctl/pkg/utils"
12-
log "github.com/sirupsen/logrus"
1311
"github.com/spf13/cobra"
14-
cmdutil "k8s.io/kubectl/pkg/cmd/util"
12+
)
13+
14+
const (
15+
AllMessagesFlag = "all-messages"
16+
AllMessagesShortFlag = "A"
17+
InternalFlag = "internal"
18+
InternalShortFlag = "i"
1519
)
1620

1721
// listCmd represents the list command
1822
var listCmd = &cobra.Command{
19-
Use: "list [flags] [options] cluster-identifier",
20-
Short: "gets all servicelog messages for a given cluster",
21-
Args: cobra.ArbitraryArgs,
22-
SilenceErrors: true,
23-
Run: func(cmd *cobra.Command, args []string) {
24-
cmdutil.CheckErr(complete(cmd, args))
25-
cmdutil.CheckErr(run(cmd, args[0]))
26-
},
27-
}
28-
29-
func complete(cmd *cobra.Command, args []string) error {
30-
if len(args) == 0 {
31-
err := cmd.Help()
23+
Use: "list [flags] [options] cluster-identifier",
24+
Short: "gets all servicelog messages for a given cluster",
25+
Args: cobra.ExactArgs(1),
26+
RunE: func(cmd *cobra.Command, args []string) error {
27+
allMessages, err := cmd.Flags().GetBool(AllMessagesFlag)
3228
if err != nil {
33-
return fmt.Errorf("error calling cmd.Help(): %w", err)
29+
return fmt.Errorf("failed to get flag `--%v`/`-%v`, %w", AllMessagesFlag, AllMessagesShortFlag, err)
30+
}
3431

32+
internalOnly, err := cmd.Flags().GetBool(InternalFlag)
33+
if err != nil {
34+
return fmt.Errorf("failed to get flag `--%v`/`-%v`, %w", InternalFlag, InternalShortFlag, err)
3535
}
36-
return fmt.Errorf("cluster-identifier was not provided. please provide a cluster id, UUID, or name")
37-
}
3836

39-
if len(args) != 1 {
40-
log.Infof("Too many arguments. Expected 1 got %d", len(args))
41-
}
37+
return ListServiceLogs(args[0], allMessages, internalOnly)
38+
},
39+
}
4240

43-
return nil
41+
func init() {
42+
// define flags
43+
listCmd.Flags().BoolP(AllMessagesFlag, AllMessagesShortFlag, false, "Toggle if we should see all of the messages or only SRE-P specific ones")
44+
listCmd.Flags().BoolP(InternalFlag, InternalShortFlag, false, "Toggle if we should see internal messages")
4445
}
4546

46-
func run(cmd *cobra.Command, clusterID string) error {
47-
response, err := FetchServiceLogs(clusterID)
47+
func ListServiceLogs(clusterID string, allMessages bool, internalOnly bool) error {
48+
response, err := FetchServiceLogs(clusterID, allMessages, internalOnly)
4849
if err != nil {
49-
// If the response has errored, likely the input was bad, so show usage
50-
helpErr := cmd.Help()
51-
if helpErr != nil {
52-
return helpErr
53-
}
54-
return err
50+
return fmt.Errorf("failed to fetch service logs: %w", err)
5551
}
5652

57-
err = dump.Pretty(os.Stdout, response.Bytes())
58-
if err != nil {
59-
// If outputing the data errored, there's likely an internal error, so just return the error
60-
return err
53+
if err = printServiceLogResponse(response); err != nil {
54+
return fmt.Errorf("failed to print service logs: %w", err)
6155
}
56+
6257
return nil
6358
}
6459

65-
var serviceLogListAllMessagesFlag = false
66-
var serviceLogListInternalOnlyFlag = false
67-
68-
func FetchServiceLogs(clusterID string) (*sdk.Response, error) {
69-
// Create OCM client to talk to cluster API
70-
ocmClient, err := utils.CreateConnection()
71-
if err != nil {
72-
return nil, err
60+
func printServiceLogResponse(response *slv1.ClustersClusterLogsListResponse) error {
61+
entryViews := logEntryToView(response.Items().Slice())
62+
view := LogEntryResponseView{
63+
Items: entryViews,
64+
Kind: "ClusterLogList",
65+
Page: response.Page(),
66+
Size: response.Size(),
67+
Total: response.Total(),
7368
}
74-
defer func() {
75-
if err := ocmClient.Close(); err != nil {
76-
fmt.Printf("Cannot close the ocmClient (possible memory leak): %q", err)
77-
}
78-
}()
7969

80-
// Use the OCM client to retrieve clusters
81-
clusters := utils.GetClusters(ocmClient, []string{clusterID})
82-
if len(clusters) != 1 {
83-
return nil, fmt.Errorf("GetClusters expected to return 1 cluster, got: %d", len(clusters))
70+
viewBytes, err := json.Marshal(view)
71+
if err != nil {
72+
return fmt.Errorf("failed to marshal response for output: %w", err)
8473
}
85-
cluster := clusters[0]
8674

87-
// Now get the SLs for the cluster
88-
return utils.SendRequest(CreateListSLRequest(ocmClient, cluster, serviceLogListAllMessagesFlag, serviceLogListInternalOnlyFlag))
75+
return dump.Pretty(os.Stdout, viewBytes)
8976
}
9077

91-
func init() {
92-
// define required flags
93-
listCmd.Flags().BoolVarP(&serviceLogListAllMessagesFlag, "all-messages", "A", serviceLogListAllMessagesFlag, "Toggle if we should see all of the messages or only SRE-P specific ones")
94-
listCmd.Flags().BoolVarP(&serviceLogListInternalOnlyFlag, "internal", "i", serviceLogListInternalOnlyFlag, "Toggle if we should see internal messages")
78+
type LogEntryResponseView struct {
79+
Items []*LogEntryView `json:"items"`
80+
Kind string `json:"kind"`
81+
Page int `json:"page"`
82+
Size int `json:"size"`
83+
Total int `json:"total"`
9584
}
9685

97-
func CreateListSLRequest(ocmClient *sdk.Connection, cluster *cmv1.Cluster, allMessages bool, internalMessages bool) *sdk.Request {
98-
// Create and populate the request:
99-
request := ocmClient.Get()
100-
err := arguments.ApplyPathArg(request, targetAPIPath)
101-
if err != nil {
102-
log.Fatalf("Can't parse API path '%s': %v\n", targetAPIPath, err)
103-
}
104-
var empty []string
105-
106-
// prefer cluster external over cluster internal ID
107-
var formatMessage string
108-
if cluster.ExternalID() != "" {
109-
formatMessage = fmt.Sprintf(`search=cluster_uuid = '%s'`, cluster.ExternalID())
110-
} else {
111-
formatMessage = fmt.Sprintf(`search=cluster_id = '%s'`, cluster.ID())
112-
}
86+
type LogEntryView struct {
87+
ClusterID string `json:"cluster_id"`
88+
ClusterUUID string `json:"cluster_uuid"`
89+
CreatedAt time.Time `json:"created_at"`
90+
CreatedBy string `json:"created_by"`
91+
Description string `json:"description"`
92+
EventStreamID string `json:"event_stream_id"`
93+
Href string `json:"href"`
94+
ID string `json:"id"`
95+
InternalOnly bool `json:"internal_only"`
96+
Kind string `json:"kind"`
97+
LogType string `json:"log_type"`
98+
ServiceName string `json:"service_name"`
99+
Severity string `json:"severity"`
100+
Summary string `json:"summary"`
101+
Timestamp time.Time `json:"timestamp"`
102+
Username string `json:"username"`
103+
}
113104

114-
if !allMessages {
115-
formatMessage += ` and service_name = 'SREManualAction'`
116-
}
117-
if internalMessages {
118-
formatMessage += ` and internal_only = 'true'`
105+
func logEntryToView(entries []*slv1.LogEntry) []*LogEntryView {
106+
entryViews := make([]*LogEntryView, 0, len(entries))
107+
for _, entry := range entries {
108+
entryView := &LogEntryView{
109+
ClusterID: entry.ClusterID(),
110+
ClusterUUID: entry.ClusterUUID(),
111+
CreatedAt: entry.CreatedAt(),
112+
CreatedBy: entry.CreatedBy(),
113+
Description: entry.Description(),
114+
EventStreamID: entry.EventStreamID(),
115+
Href: entry.HREF(),
116+
ID: entry.ID(),
117+
InternalOnly: entry.InternalOnly(),
118+
Kind: entry.Kind(),
119+
LogType: string(entry.LogType()),
120+
ServiceName: entry.ServiceName(),
121+
Severity: string(entry.Severity()),
122+
Summary: entry.Summary(),
123+
Timestamp: entry.Timestamp(),
124+
Username: entry.Username(),
125+
}
126+
entryViews = append(entryViews, entryView)
119127
}
120-
arguments.ApplyParameterFlag(request, []string{formatMessage})
121-
arguments.ApplyHeaderFlag(request, empty)
122-
return request
128+
return entryViews
123129
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ require (
3030
github.com/onsi/ginkgo v1.16.5
3131
github.com/onsi/gomega v1.27.7
3232
github.com/openshift-online/ocm-cli v0.1.66
33-
github.com/openshift-online/ocm-sdk-go v0.1.344
33+
github.com/openshift-online/ocm-sdk-go v0.1.372
3434
github.com/openshift/api v0.0.0-20230320211411-560b2fb170af
3535
github.com/openshift/aws-account-operator/api v0.0.0-20230322125717-5b5a00a3e99f
3636
github.com/openshift/backplane-cli v0.1.5

0 commit comments

Comments
 (0)