Skip to content

Commit

Permalink
feat: add SMI log collector
Browse files Browse the repository at this point in the history
Add log collector for Service Mesh Interface
logs, CustomResourceDefinitions, and custom
resources.

Related to PR Azure#48.

Resolves issue Azure#67.

Signed-off-by: Johnson Shi <[email protected]>
  • Loading branch information
johnsonshi committed Jul 7, 2021
1 parent fc965f2 commit 45af0a3
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 2 deletions.
5 changes: 5 additions & 0 deletions cmd/aks-periscope/aks-periscope.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func main() {
systemPerfCollector := collector.NewSystemPerfCollector()
helmCollector := collector.NewHelmCollector()
osmCollector := collector.NewOsmCollector()
smiCollector := collector.NewSmiCollector(exporter)

collectors := []interfaces.Collector{
containerLogsCollector,
Expand All @@ -75,6 +76,10 @@ func main() {
collectors = append(collectors, osmCollector)
}

if contains(collectorList, "SMI") {
collectors = append(collectors, smiCollector)
}

collectorGrp := new(sync.WaitGroup)

for _, c := range collectors {
Expand Down
7 changes: 5 additions & 2 deletions deployment/aks-periscope.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ rules:
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
verbs: ["get", "list", "watch"]
- apiGroups: ["access.smi-spec.io", "specs.smi-spec.io", "split.smi-spec.io"]
resources: ["*"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
Expand Down Expand Up @@ -77,7 +80,7 @@ spec:
beta.kubernetes.io/os: linux
containers:
- name: aks-periscope
image: aksrepos.azurecr.io/staging/aks-periscope:v0.3
image: johshmsft/aks-periscope:latest
securityContext:
privileged: true
imagePullPolicy: Always
Expand Down Expand Up @@ -148,7 +151,7 @@ metadata:
name: collectors-config
namespace: aks-periscope
data:
COLLECTOR_LIST: managedCluster # <custom flag>
COLLECTOR_LIST: managedCluster, OSM, SMI # <custom flag>
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
Expand Down
107 changes: 107 additions & 0 deletions pkg/collector/smi_collector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package collector

import (
"log"
"path/filepath"
"strings"

"github.com/Azure/aks-periscope/pkg/utils"
)

// SmiCollector defines an Smi Collector struct
type SmiCollector struct {
data map[string]string
}

// NewSmiCollector is a constructor
func NewSmiCollector() *SmiCollector {
return &SmiCollector{
data: make(map[string]string),
}
}

func (collector *SmiCollector) GetName() string {
return "smi"
}

// Collect implements the interface method
func (collector *SmiCollector) Collect() error {
// Get all CustomResourceDefinitions in the cluster
allCrdsList, err := utils.GetResourceList([]string{"get", "crds", "-o", "jsonpath={..metadata.name}"}, " ")
if err != nil {
return err
}

// Directory where logs will be written to
rootPath, err := utils.CreateCollectorDir(collector.GetName())
if err != nil {
return err
}

// Filter to obtain a list of Smi CustomResourceDefinitions in the cluster
crdNameContainsSmiPredicate := func(s string) bool { return strings.Contains(s, "smi-spec.io") }
smiCrdsList := filter(allCrdsList, crdNameContainsSmiPredicate)
if len(smiCrdsList) == 0 {
// TODO should this return an error?
log.Printf("Cluster does not contain any SMI CustomResourceDefinitions\n")
return nil
}

collectSmiCrdDefinitions(collector, filepath.Join(rootPath, "smi_crd_definitions"), smiCrdsList)
collectSmiCustomResourcesFromAllNamespaces(collector, filepath.Join(rootPath, "smi_custom_resources"), smiCrdsList)

return nil
}

func collectSmiCrdDefinitions(collector *SmiCollector, rootPath string, smiCrdsList []string) {
for _, smiCrd := range smiCrdsList {
fileName := smiCrd + "_definition.yaml"
kubeCmd := []string{"get", "crd", smiCrd, "-o", "yaml"}
if err := collector.CollectKubectlOutputToCollectorFiles(rootPath, fileName, kubeCmd); err != nil {
log.Printf("Failed to collect %s: %+v", fileName, err)
}
}
}

func collectSmiCustomResourcesFromAllNamespaces(collector *SmiCollector, rootPath string, smiCrdsList []string) {
// Get all namespaces in the cluster
namespacesList, err := utils.GetResourceList([]string{"get", "namespaces", "-o", "jsonpath={..metadata.name}"}, " ")
if err != nil {
log.Printf("Failed to list namespaces in the cluster: %+v", err)
return
}

for _, namespace := range namespacesList {
namespaceRootPath := filepath.Join(rootPath, "namespace_"+namespace)
collectSmiCustomResourcesFromSingleNamespace(collector, namespaceRootPath, smiCrdsList, namespace)
}
}

func collectSmiCustomResourcesFromSingleNamespace(collector *SmiCollector, rootPath string, smiCrdsList []string, namespace string) {
for _, smiCrdType := range smiCrdsList {
// get all custom resources of this smi crd type
customResourcesList, err := utils.GetResourceList([]string{"get", smiCrdType, "-n", namespace, "-o", "jsonpath={..metadata.name}"}, " ")
if err != nil {
log.Printf("Failed to list custom resources of type %s in namespace %s: %+v", smiCrdType, namespace, err)
continue
}

customResourcesRootPath := filepath.Join(rootPath, smiCrdType+"_custom_resources")
for _, customResourceName := range customResourcesList {
fileName := smiCrdType + "_" + customResourceName + ".yaml"
kubeCmd := []string{"get", smiCrdType, customResourceName, "-n", namespace, "-o", "yaml"}
if err := collector.CollectKubectlOutputToCollectorFiles(customResourcesRootPath, fileName, kubeCmd); err != nil {
log.Printf("Failed to collect %s: %+v", fileName, err)
}
}
}
}

func filter(ss []string, test func(string) bool) (ret []string) {
for _, s := range ss {
if test(s) {
ret = append(ret, s)
}
}
return
}

0 comments on commit 45af0a3

Please sign in to comment.