This is an automated email from the ASF dual-hosted git repository.

kezhenxu94 pushed a commit to branch enhance
in repository 
https://gitbox.apache.org/repos/asf/skywalking-kubernetes-event-exporter.git

commit dfd605022755bf08185f592583ec65d18389ccdf
Author: kezhenxu94 <[email protected]>
AuthorDate: Thu May 13 22:49:21 2021 +0800

    Add Console exporter, source filter
---
 README.md                                         |   4 +
 assets/default-config.yaml                        |   9 +-
 configs/config.go                                 |  17 ++-
 docs/exporters.md                                 |  14 +++
 assets/default-config.yaml => examples/debug.yaml |  14 +--
 pkg/exporter/console.go                           | 121 ++++++++++++++++++++++
 pkg/exporter/skywalking.go                        |   5 +-
 7 files changed, 168 insertions(+), 16 deletions(-)

diff --git a/README.md b/README.md
index eccc635..fd90561 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,10 @@ specified in the command line interface nor config map 
created in Kubernetes.
 All available configuration items and their documentations can be found
 in [the default configuration file](assets/default-config.yaml).
 
+## Exporters
+
+The available exporters are listed [here](docs/exporters.md).
+
 ## Deployments
 
 Go to [the /deployments/release](deployments/release) directory, modify 
according to your needs, and
diff --git a/assets/default-config.yaml b/assets/default-config.yaml
index 11bde2a..27753d3 100644
--- a/assets/default-config.yaml
+++ b/assets/default-config.yaml
@@ -17,14 +17,15 @@
 #
 
 filters:
-  - reason: ""     # filter events of the specified reason, regular expression 
like "Killing|Killed" is supported.
+  - reason: "Started|Killing"     # filter events of the specified reason, 
regular expression like "Killing|Killed" is supported.
     message: ""    # filter events of the specified message, regular 
expression like "Pulling container.*" is supported.
     minCount: 1    # filter events whose count is >= the specified value.
     type: ""       # filter events of the specified type, regular expression 
like "Normal|Error" is supported.
     action: ""     # filter events of the specified action, regular expression 
is supported.
-    kind: ""       # filter events of the specified kind, regular expression 
like "Pod|Service" is supported.
-    namespace: ""  # filter events from the specified namespace, regular 
expression like "default|bookinfo" is supported, empty means all namespaces.
-    name: ""       # filter events from the specified namespace, regular 
expression like ".*bookinfo.*" is supported.
+    kind: "Pod|Service"       # filter events of the specified kind, regular 
expression like "Pod|Service" is supported.
+    namespace: "default"  # filter events from the specified namespace, 
regular expression like "default|bookinfo" is supported, empty means all 
namespaces.
+    name: ""       # filter events of the specified involved object name, 
regular expression like ".*bookinfo.*" is supported.
+    service: "[^\\s]{1,}"  # filter events belonging to services whose name is 
not empty.
     exporters:     # events satisfy this filter can be exported into several 
exporters that are defined in the `exporters` section below.
       - skywalking
 
diff --git a/configs/config.go b/configs/config.go
index 04558dd..7243776 100644
--- a/configs/config.go
+++ b/configs/config.go
@@ -21,7 +21,9 @@ package configs
 
 import (
        "regexp"
+       "strings"
 
+       "github.com/apache/skywalking-kubernetes-event-exporter/pkg/k8s"
        "gopkg.in/yaml.v3"
        v1 "k8s.io/api/core/v1"
 
@@ -46,6 +48,8 @@ type FilterConfig struct {
        namespaceRegExp *regexp.Regexp
        Name            string `yaml:"name"`
        nameRegExp      *regexp.Regexp
+       Service         string `yaml:"service"`
+       serviceRegExp   *regexp.Regexp
 
        Exporters []string `yaml:"exporters"`
 }
@@ -60,6 +64,7 @@ func (filter *FilterConfig) Init() {
        filter.kindRegExp = regexp.MustCompile(filter.Kind)
        filter.namespaceRegExp = regexp.MustCompile(filter.Namespace)
        filter.nameRegExp = regexp.MustCompile(filter.Name)
+       filter.serviceRegExp = regexp.MustCompile(filter.Service)
 }
 
 // Filter the given event with this filter instance.
@@ -83,15 +88,21 @@ func (filter *FilterConfig) Filter(event *v1.Event) bool {
        if filter.Action != "" && 
!filter.actionRegExp.MatchString(event.Action) {
                return true
        }
-       if filter.Kind != "" && !filter.kindRegExp.MatchString(event.Kind) {
+       if filter.Kind != "" && 
!filter.kindRegExp.MatchString(event.InvolvedObject.Kind) {
                return true
        }
-       if filter.Namespace != "" && 
!filter.namespaceRegExp.MatchString(event.Namespace) {
+       if filter.Namespace != "" && 
!filter.namespaceRegExp.MatchString(event.InvolvedObject.Namespace) {
                return true
        }
-       if filter.Name != "" && !filter.nameRegExp.MatchString(event.Name) {
+       if filter.Name != "" && 
!filter.nameRegExp.MatchString(event.InvolvedObject.Name) {
                return true
        }
+       if filter.Service != "" {
+               context := k8s.Registry.GetContext(event)
+               if svcName := strings.TrimSpace(context.Service.Name); 
!filter.serviceRegExp.MatchString(svcName) {
+                       return true
+               }
+       }
        return false
 }
 
diff --git a/docs/exporters.md b/docs/exporters.md
new file mode 100644
index 0000000..b0fedd3
--- /dev/null
+++ b/docs/exporters.md
@@ -0,0 +1,14 @@
+# Exporters
+
+## SkyWalking
+
+[SkyWalking Exporter](../pkg/exporter/skywalking.go) exports the events into 
Apache SkyWalking OAP server.
+
+The configurations of SkyWalking Exporter can be found 
[here](../assets/default-config.yaml).
+
+## Console
+
+[Console Exporter](../pkg/exporter/console.go) exports the events into console 
logs, this exporter is typically used for
+debugging.
+
+The configurations of Console Exporter can be found 
[here](../assets/default-config.yaml).
diff --git a/assets/default-config.yaml b/examples/debug.yaml
similarity index 71%
copy from assets/default-config.yaml
copy to examples/debug.yaml
index 11bde2a..603867d 100644
--- a/assets/default-config.yaml
+++ b/examples/debug.yaml
@@ -17,19 +17,20 @@
 #
 
 filters:
-  - reason: ""     # filter events of the specified reason, regular expression 
like "Killing|Killed" is supported.
+  - reason: "Started|Killing"     # filter events of the specified reason, 
regular expression like "Killing|Killed" is supported.
     message: ""    # filter events of the specified message, regular 
expression like "Pulling container.*" is supported.
     minCount: 1    # filter events whose count is >= the specified value.
     type: ""       # filter events of the specified type, regular expression 
like "Normal|Error" is supported.
     action: ""     # filter events of the specified action, regular expression 
is supported.
-    kind: ""       # filter events of the specified kind, regular expression 
like "Pod|Service" is supported.
-    namespace: ""  # filter events from the specified namespace, regular 
expression like "default|bookinfo" is supported, empty means all namespaces.
-    name: ""       # filter events from the specified namespace, regular 
expression like ".*bookinfo.*" is supported.
+    kind: "Pod|Service"       # filter events of the specified kind, regular 
expression like "Pod|Service" is supported.
+    namespace: "default"  # filter events from the specified namespace, 
regular expression like "default|bookinfo" is supported, empty means all 
namespaces.
+    name: ""       # filter events of the specified involved object name, 
regular expression like ".*bookinfo.*" is supported.
+    service: "[^\\s]{1,}"  # filter events belonging to services whose name is 
not empty.
     exporters:     # events satisfy this filter can be exported into several 
exporters that are defined in the `exporters` section below.
-      - skywalking
+      - console
 
 exporters:         # defines and configures the exporters that can be used in 
the `filters` section above.
-  skywalking:      # the exporter name, which is declared in the struct type 
`Exporter`'s Name function.
+  console:      # the exporter name, which is declared in the struct type 
`Exporter`'s Name function.
     # Below are exporter-specific configurations, different exporter may have 
different configuration contents.
     template:      # the event template of SkyWalking exporter, it can be 
composed of metadata like Event, Pod, and Service.
       source:
@@ -37,4 +38,3 @@ exporters:         # defines and configures the exporters 
that can be used in th
         serviceInstance: "{{ .Pod.Name }}"
         endpoint: ""
       message: "{{ .Event.Message }}" # this is default, just to demonstrate 
the context
-    address: "127.0.0.1:11800" # the SkyWalking backend address where this 
exporter will export to.
diff --git a/pkg/exporter/console.go b/pkg/exporter/console.go
new file mode 100644
index 0000000..05a5b1f
--- /dev/null
+++ b/pkg/exporter/console.go
@@ -0,0 +1,121 @@
+/*
+ * Licensed to Apache Software Foundation (ASF) under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Apache Software Foundation (ASF) licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package exporter
+
+import (
+       "encoding/json"
+       "fmt"
+       sw "skywalking.apache.org/repo/goapi/collect/event/v3"
+
+       k8score "k8s.io/api/core/v1"
+
+       "github.com/apache/skywalking-kubernetes-event-exporter/configs"
+       
"github.com/apache/skywalking-kubernetes-event-exporter/internal/pkg/logger"
+       "github.com/apache/skywalking-kubernetes-event-exporter/pkg/event"
+)
+
+// Console Exporter exports the events into console logs, this exporter is 
typically
+// used for debugging.
+type Console struct {
+       config  ConsoleConfig
+       stopper chan struct{}
+}
+
+type ConsoleConfig struct {
+       Template *EventTemplate `mapstructure:"template"`
+}
+
+func init() {
+       s := &Console{
+               stopper: make(chan struct{}),
+       }
+       RegisterExporter(s.Name(), s)
+}
+
+func (exporter *Console) Init() error {
+       config := ConsoleConfig{}
+
+       if c := configs.GlobalConfig.Exporters[exporter.Name()]; c == nil {
+               return fmt.Errorf("configs of %+v exporter cannot be empty", 
exporter.Name())
+       } else if marshal, err := json.Marshal(c); err != nil {
+               return err
+       } else if err := json.Unmarshal(marshal, &config); err != nil {
+               return err
+       }
+
+       if err := config.Template.Init(); err != nil {
+               return err
+       }
+
+       exporter.config = config
+
+       return nil
+}
+
+func (exporter *Console) Name() string {
+       return "console"
+}
+
+func (exporter *Console) Export(events chan *k8score.Event) {
+       logger.Log.Debugf("exporting events into %+v", exporter.Name())
+
+       func() {
+               for {
+                       select {
+                       case <-exporter.stopper:
+                               drain(events)
+                               return
+                       case kEvent := <-events:
+                               if kEvent == event.Stopper {
+                                       return
+                               }
+                               logger.Log.Debugf("exporting event to %v: %v", 
exporter.Name(), kEvent)
+
+                               t := sw.Type_Normal
+                               if kEvent.Type == "Warning" {
+                                       t = sw.Type_Error
+                               }
+                               swEvent := &sw.Event{
+                                       Uuid:      string(kEvent.UID),
+                                       Source:    &sw.Source{},
+                                       Name:      kEvent.Reason,
+                                       Type:      t,
+                                       Message:   kEvent.Message,
+                                       StartTime: 
kEvent.FirstTimestamp.UnixNano() / 1000000,
+                                       EndTime:   kEvent.LastTimestamp.Unix() 
/ 1000000,
+                               }
+                               if exporter.config.Template != nil {
+                                       
exporter.config.Template.render(swEvent, kEvent)
+                                       logger.Log.Debugf("rendered event is: 
%+v", swEvent)
+                               }
+                               if bytes, err := json.Marshal(swEvent); err != 
nil {
+                                       logger.Log.Errorf("failed to send event 
to %+v, %+v", exporter.Name(), err)
+                               } else {
+                                       logger.Log.Infoln(string(bytes))
+                               }
+                       }
+               }
+       }()
+}
+
+func (exporter *Console) Stop() {
+       exporter.stopper <- struct{}{}
+       close(exporter.stopper)
+}
diff --git a/pkg/exporter/skywalking.go b/pkg/exporter/skywalking.go
index 015408b..7319bf4 100644
--- a/pkg/exporter/skywalking.go
+++ b/pkg/exporter/skywalking.go
@@ -39,6 +39,7 @@ import (
        "github.com/apache/skywalking-kubernetes-event-exporter/pkg/event"
 )
 
+// SkyWalking Exporter exports the events into Apache SkyWalking OAP server.
 type SkyWalking struct {
        config     SkyWalkingConfig
        client     sw.EventServiceClient
@@ -138,7 +139,7 @@ func (exporter *SkyWalking) Export(events chan 
*k8score.Event) {
                                        EndTime:   kEvent.LastTimestamp.Unix() 
/ 1000000,
                                }
                                if exporter.config.Template != nil {
-                                       
exporter.config.Template.Render(swEvent, kEvent)
+                                       
exporter.config.Template.render(swEvent, kEvent)
                                        logger.Log.Debugf("rendered event is: 
%+v", swEvent)
                                }
                                if err := stream.Send(swEvent); err != nil {
@@ -149,7 +150,7 @@ func (exporter *SkyWalking) Export(events chan 
*k8score.Event) {
        }()
 }
 
-func (tmplt *EventTemplate) Render(swEvent *sw.Event, kEvent *k8score.Event) {
+func (tmplt *EventTemplate) render(swEvent *sw.Event, kEvent *k8score.Event) {
        templateCtx := k8s.Registry.GetContext(kEvent)
 
        logger.Log.Debugf("template context %+v", templateCtx)

Reply via email to