Skip to content

Commit afe161a

Browse files
author
Serhii Zakharov
authored
sap license management logs gatherer (#342)
* sap license management logs gatherer * added docs * fixed tests * removed debug dockerfile * fixes due to code review * fixes due to code review * merged-constants-files * added sample for the archive
1 parent f4e8374 commit afe161a

File tree

13 files changed

+254
-83
lines changed

13 files changed

+254
-83
lines changed

Diff for: docs/gathered-data.md

+12
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,18 @@ Relevant OpenShift API docs:
399399
Location in archive: config/securitycontentconstraint/, config/clusterrolebinding/
400400

401401

402+
## SAPVsystemIptablesLogs
403+
404+
collects logs from SAP vsystem-iptables containers
405+
including one from license management pods with the following substring:
406+
- "can't initialize iptables table",
407+
408+
The Kubernetes API https://github.com/kubernetes/client-go/blob/master/kubernetes/typed/core/v1/pod_expansion.go#L48
409+
Response see https://docs.openshift.com/container-platform/4.6/rest_api/workloads_apis/pod-core-v1.html#apiv1namespacesnamespacepodsnamelog
410+
411+
Location in archive: config/pod/{namespace}/logs/{pod-name}/errors.log
412+
413+
402414
## ServiceAccounts
403415

404416
collects ServiceAccount stats
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
iptables v1.6.2: can't initialize iptables table `nat': Permission denied

Diff for: pkg/gather/clusterconfig/0_gatherer.go

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ var gatherFunctions = map[string]gathering{
8484
"openshift_sdn_controller_logs": failable(GatherOpenshiftSDNControllerLogs),
8585
"openshift_authentication_logs": failable(GatherOpenshiftAuthenticationLogs),
8686
"sap_config": failable(GatherSAPConfig),
87+
"sap_license_management_logs": failable(GatherSAPVsystemIptablesLogs),
8788
"olm_operators": failable(GatherOLMOperators),
8889
}
8990

Diff for: pkg/gather/clusterconfig/const.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import (
44
"time"
55

66
registryv1 "github.com/openshift/api/imageregistry/v1"
7-
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
8-
97
"k8s.io/apimachinery/pkg/runtime"
8+
"k8s.io/apimachinery/pkg/runtime/schema"
9+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
1010
)
1111

1212
const (
@@ -20,7 +20,10 @@ var (
2020
// logTailLines sets maximum number of lines to fetch from pod logs
2121
logTailLines = int64(100)
2222

23-
defaultNamespaces = []string{"default", "kube-system", "kube-public"}
23+
defaultNamespaces = []string{"default", "kube-system", "kube-public"}
24+
datahubGroupVersionResource = schema.GroupVersionResource{
25+
Group: "installers.datahub.sap.com", Version: "v1alpha1", Resource: "datahubs",
26+
}
2427
)
2528

2629
func init() {

Diff for: pkg/gather/clusterconfig/gather_logs.go

+54-22
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,42 @@ import (
1717
"github.com/openshift/insights-operator/pkg/utils/marshal"
1818
)
1919

20-
// gatherLogsFromPodsInNamespace collects logs from the pods in provided namespace
21-
// - messagesToSearch are the messages to filter the logs(case-insensitive)
22-
// - sinceSeconds sets the moment to fetch logs from(current time - sinceSeconds)
23-
// - limitBytes sets the maximum amount of logs that can be fetched
24-
// - logFileName sets the name of the file to save logs to.
25-
// - labelSelector allows you to filter pods by their labels
26-
// - regexSearch makes messagesToSearch regex patterns, so you can accomplish more complicated search
20+
type logContainersFilter struct {
21+
namespace string
22+
labelSelector string
23+
containerNameRegexFilter string
24+
}
25+
26+
type logMessagesFilter struct {
27+
messagesToSearch []string
28+
isRegexSearch bool
29+
sinceSeconds int64
30+
limitBytes int64
31+
}
32+
33+
// gatherLogsFromContainers collects logs from containers
34+
// - containerFilter allows you to specify
35+
// - namespace in which to search for pods
36+
// - labelSelector to filter pods by their labels (keep empty to not filter)
37+
// - containerNameRegexFilter to filter containers in the pod (keep empty to not filter)
38+
// - logMessagesFilter allows you to specify
39+
// - messagesToSearch to filter the logs by substrings (case-insensitive)
40+
// or regex (add `(?i)` in the beginning to make search case-insensitive)
41+
// - regexSearch which makes messagesToSearch regex patterns, so you can accomplish more complicated search
42+
// - sinceSeconds which sets the moment to fetch the logs from (current time - sinceSeconds)
43+
// - limitBytes which sets the maximum amount of logs that can be fetched
44+
// - logFileName sets the name of the file to save the logs to.
2745
//
2846
// Location of the logs is `config/pod/{namespace}/logs/{podName}/{fileName}.log`
29-
func gatherLogsFromPodsInNamespace(
47+
func gatherLogsFromContainers(
3048
ctx context.Context,
3149
coreClient v1.CoreV1Interface,
32-
namespace string,
33-
messagesToSearch []string,
34-
sinceSeconds int64,
35-
limitBytes int64,
50+
containersFilter logContainersFilter,
51+
messagesFilter logMessagesFilter,
3652
logFileName string,
37-
labelSelector string,
38-
regexSearch bool,
3953
) ([]record.Record, error) {
40-
pods, err := coreClient.Pods(namespace).List(ctx, metav1.ListOptions{
41-
LabelSelector: labelSelector,
54+
pods, err := coreClient.Pods(containersFilter.namespace).List(ctx, metav1.ListOptions{
55+
LabelSelector: containersFilter.labelSelector,
4256
})
4357
if err != nil {
4458
return nil, err
@@ -47,14 +61,32 @@ func gatherLogsFromPodsInNamespace(
4761
var records []record.Record
4862

4963
for _, pod := range pods.Items {
64+
var containers []string
5065
for _, container := range pod.Spec.Containers {
51-
request := coreClient.Pods(namespace).GetLogs(pod.Name, &corev1.PodLogOptions{
52-
Container: container.Name,
53-
SinceSeconds: &sinceSeconds,
54-
LimitBytes: &limitBytes,
66+
containers = append(containers, container.Name)
67+
}
68+
for _, container := range pod.Spec.InitContainers {
69+
containers = append(containers, container.Name)
70+
}
71+
72+
for _, container := range containers {
73+
if len(containersFilter.containerNameRegexFilter) > 0 {
74+
match, err := regexp.MatchString(containersFilter.containerNameRegexFilter, container)
75+
if err != nil {
76+
return nil, err
77+
}
78+
if !match {
79+
continue
80+
}
81+
}
82+
83+
request := coreClient.Pods(containersFilter.namespace).GetLogs(pod.Name, &corev1.PodLogOptions{
84+
Container: container,
85+
SinceSeconds: &messagesFilter.sinceSeconds,
86+
LimitBytes: &messagesFilter.limitBytes,
5587
})
5688

57-
logs, err := filterLogs(ctx, request, messagesToSearch, regexSearch)
89+
logs, err := filterLogs(ctx, request, messagesFilter.messagesToSearch, messagesFilter.isRegexSearch)
5890
if err != nil {
5991
return nil, err
6092
}
@@ -69,7 +101,7 @@ func gatherLogsFromPodsInNamespace(
69101
}
70102

71103
if len(pods.Items) == 0 {
72-
klog.Infof("no pods in %v namespace were found", namespace)
104+
klog.Infof("no pods in %v namespace were found", containersFilter.namespace)
73105
}
74106

75107
return records, nil

Diff for: pkg/gather/clusterconfig/gather_logs_test.go

+11-8
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,21 @@ func testGatherLogs(t *testing.T, regexSearch bool, stringToSearch string, shoul
4545
t.Fatal(err)
4646
}
4747

48-
records, err := gatherLogsFromPodsInNamespace(
48+
records, err := gatherLogsFromContainers(
4949
ctx,
5050
coreClient,
51-
testPodName,
52-
[]string{
53-
stringToSearch,
51+
logContainersFilter{
52+
namespace: testPodName,
53+
},
54+
logMessagesFilter{
55+
messagesToSearch: []string{
56+
stringToSearch,
57+
},
58+
isRegexSearch: regexSearch,
59+
sinceSeconds: 86400, // last day
60+
limitBytes: 1024 * 64, // maximum 64 kb of logs
5461
},
55-
86400, // last day
56-
1024*64, // maximum 64 kb of logs
5762
testLogFileName,
58-
"",
59-
regexSearch,
6063
)
6164
if err != nil {
6265
t.Fatal(err)

Diff for: pkg/gather/clusterconfig/openshift_apiserver_operator_logs.go

+16-10
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,19 @@ import (
1414
// Location in archive: config/pod/{namespace-name}/logs/{pod-name}/errors.log
1515
func GatherOpenShiftAPIServerOperatorLogs(g *Gatherer, c chan<- gatherResult) {
1616
defer close(c)
17-
messagesToSearch := []string{
18-
"the server has received too many requests and has asked us",
19-
"because serving request timed out and response had been started",
17+
18+
containersFilter := logContainersFilter{
19+
namespace: "openshift-apiserver-operator",
20+
labelSelector: "app=openshift-apiserver-operator",
21+
}
22+
messagesFilter := logMessagesFilter{
23+
messagesToSearch: []string{
24+
"the server has received too many requests and has asked us",
25+
"because serving request timed out and response had been started",
26+
},
27+
isRegexSearch: false,
28+
sinceSeconds: 86400, // last day
29+
limitBytes: 1024 * 64, // maximum 64 kb of logs
2030
}
2131

2232
gatherKubeClient, err := kubernetes.NewForConfig(g.gatherProtoKubeConfig)
@@ -27,16 +37,12 @@ func GatherOpenShiftAPIServerOperatorLogs(g *Gatherer, c chan<- gatherResult) {
2737

2838
coreClient := gatherKubeClient.CoreV1()
2939

30-
records, err := gatherLogsFromPodsInNamespace(
40+
records, err := gatherLogsFromContainers(
3141
g.ctx,
3242
coreClient,
33-
"openshift-apiserver-operator",
34-
messagesToSearch,
35-
86400, // last day
36-
1024*64, // maximum 64 kb of logs
43+
containersFilter,
44+
messagesFilter,
3745
"errors",
38-
"app=openshift-apiserver-operator",
39-
false,
4046
)
4147
if err != nil {
4248
c <- gatherResult{nil, []error{err}}

Diff for: pkg/gather/clusterconfig/openshift_authentication_logs.go

+15-9
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,18 @@ import (
1212
//
1313
// Location in archive: config/pod/openshift-authentication/logs/{pod-name}/errors.log
1414
func GatherOpenshiftAuthenticationLogs(g *Gatherer, c chan<- gatherResult) {
15-
messagesToSearch := []string{
16-
"AuthenticationError: invalid resource name",
15+
defer close(c)
16+
17+
containersFilter := logContainersFilter{
18+
namespace: "openshift-authentication",
19+
}
20+
messagesFilter := logMessagesFilter{
21+
messagesToSearch: []string{
22+
"AuthenticationError: invalid resource name",
23+
},
24+
isRegexSearch: false,
25+
sinceSeconds: 86400, // last day
26+
limitBytes: 1024 * 64, // maximum 64 kb of logs
1727
}
1828

1929
gatherKubeClient, err := kubernetes.NewForConfig(g.gatherProtoKubeConfig)
@@ -24,16 +34,12 @@ func GatherOpenshiftAuthenticationLogs(g *Gatherer, c chan<- gatherResult) {
2434

2535
coreClient := gatherKubeClient.CoreV1()
2636

27-
records, err := gatherLogsFromPodsInNamespace(
37+
records, err := gatherLogsFromContainers(
2838
g.ctx,
2939
coreClient,
30-
"openshift-authentication",
31-
messagesToSearch,
32-
86400, // last day
33-
1024*64, // maximum 64 kb of logs
40+
containersFilter,
41+
messagesFilter,
3442
"errors",
35-
"",
36-
false,
3743
)
3844
if err != nil {
3945
c <- gatherResult{nil, []error{err}}

Diff for: pkg/gather/clusterconfig/openshift_sdn_controller_logs.go

+19-12
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,22 @@ import (
2121
//
2222
// Location in archive: config/pod/openshift-sdn/logs/{pod-name}/errors.log
2323
func GatherOpenshiftSDNControllerLogs(g *Gatherer, c chan<- gatherResult) {
24-
messagesToSearch := []string{
25-
"Node.+is not Ready",
26-
"Node.+may be offline\\.\\.\\. retrying",
27-
"Node.+is offline",
28-
"Node.+is back online",
24+
defer close(c)
25+
26+
containersFilter := logContainersFilter{
27+
namespace: "openshift-sdn",
28+
labelSelector: "app=sdn-controller",
29+
}
30+
messagesFilter := logMessagesFilter{
31+
messagesToSearch: []string{
32+
"Node.+is not Ready",
33+
"Node.+may be offline\\.\\.\\. retrying",
34+
"Node.+is offline",
35+
"Node.+is back online",
36+
},
37+
isRegexSearch: true,
38+
sinceSeconds: 86400, // last day
39+
limitBytes: 1024 * 64, // maximum 64 kb of logs
2940
}
3041

3142
gatherKubeClient, err := kubernetes.NewForConfig(g.gatherProtoKubeConfig)
@@ -36,16 +47,12 @@ func GatherOpenshiftSDNControllerLogs(g *Gatherer, c chan<- gatherResult) {
3647

3748
coreClient := gatherKubeClient.CoreV1()
3849

39-
records, err := gatherLogsFromPodsInNamespace(
50+
records, err := gatherLogsFromContainers(
4051
g.ctx,
4152
coreClient,
42-
"openshift-sdn",
43-
messagesToSearch,
44-
86400, // last day
45-
1024*64, // maximum 64 kb of logs
53+
containersFilter,
54+
messagesFilter,
4655
"errors",
47-
"app=sdn-controller",
48-
true,
4956
)
5057
if err != nil {
5158
c <- gatherResult{nil, []error{err}}

Diff for: pkg/gather/clusterconfig/openshift_sdn_logs.go

+18-12
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,21 @@ import (
1616
// Location in archive: config/pod/openshift-sdn/logs/{pod-name}/errors.log
1717
func GatherOpenshiftSDNLogs(g *Gatherer, c chan<- gatherResult) {
1818
defer close(c)
19-
messagesToSearch := []string{
20-
"Got OnEndpointsUpdate for unknown Endpoints",
21-
"Got OnEndpointsDelete for unknown Endpoints",
22-
"Unable to update proxy firewall for policy",
23-
"Failed to update proxy firewall for policy",
19+
20+
containersFilter := logContainersFilter{
21+
namespace: "openshift-sdn",
22+
labelSelector: "app=sdn",
23+
}
24+
messagesFilter := logMessagesFilter{
25+
messagesToSearch: []string{
26+
"Got OnEndpointsUpdate for unknown Endpoints",
27+
"Got OnEndpointsDelete for unknown Endpoints",
28+
"Unable to update proxy firewall for policy",
29+
"Failed to update proxy firewall for policy",
30+
},
31+
isRegexSearch: false,
32+
sinceSeconds: 86400,
33+
limitBytes: 1024 * 64,
2434
}
2535

2636
gatherKubeClient, err := kubernetes.NewForConfig(g.gatherProtoKubeConfig)
@@ -31,16 +41,12 @@ func GatherOpenshiftSDNLogs(g *Gatherer, c chan<- gatherResult) {
3141

3242
coreClient := gatherKubeClient.CoreV1()
3343

34-
records, err := gatherLogsFromPodsInNamespace(
44+
records, err := gatherLogsFromContainers(
3545
g.ctx,
3646
coreClient,
37-
"openshift-sdn",
38-
messagesToSearch,
39-
86400, // last day
40-
1024*64, // maximum 64 kb of logs
47+
containersFilter,
48+
messagesFilter,
4149
"errors",
42-
"app=sdn",
43-
false,
4450
)
4551
if err != nil {
4652
c <- gatherResult{nil, []error{err}}

Diff for: pkg/gather/clusterconfig/sap_config.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77

88
"k8s.io/apimachinery/pkg/api/errors"
99
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10-
"k8s.io/apimachinery/pkg/runtime/schema"
1110
"k8s.io/client-go/dynamic"
1211
"k8s.io/client-go/kubernetes"
1312
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
@@ -56,9 +55,7 @@ func gatherSAPConfig(ctx context.Context, dynamicClient dynamic.Interface, coreC
5655
sccToGather := []string{"anyuid", "privileged"}
5756
crbToGather := []string{"system:openshift:scc:anyuid", "system:openshift:scc:privileged"}
5857

59-
datahubsResource := schema.GroupVersionResource{Group: "installers.datahub.sap.com", Version: "v1alpha1", Resource: "datahubs"}
60-
61-
datahubsList, err := dynamicClient.Resource(datahubsResource).List(ctx, metav1.ListOptions{})
58+
datahubsList, err := dynamicClient.Resource(datahubGroupVersionResource).List(ctx, metav1.ListOptions{})
6259
if errors.IsNotFound(err) {
6360
return nil, nil
6461
}

0 commit comments

Comments
 (0)