Greg Padgett has uploaded a new change for review.

Change subject: tools: notifier: filter messages based on severity
......................................................................

tools: notifier: filter messages based on severity

Extend the existing notifier filter mechanism to accept severities in an
extra, optional field:

  PATTERN=include|exclude:event[:severity][(subscriber)]

The parser accepts the prior format for backwards compatibility.

An inclusion filter will match an event with greater-or-equal severity.
Conversely, an exclusion filter will match an event with lesser-or-equal
severity.

Change-Id: Ia8abc34d56f1ede2fb51daf71dee293d08f198a3
Signed-off-by: Greg Padgett <[email protected]>
---
M 
backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/NotificationService.java
M 
backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/dao/EventsManager.java
M 
backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/filter/FirstMatchSimpleFilter.java
M 
backend/manager/tools/src/test/java/org/ovirt/engine/core/notifier/filter/FirstMatchSimpleFilterTest.java
M packaging/services/ovirt-engine-notifier/ovirt-engine-notifier.conf.in
5 files changed, 120 insertions(+), 11 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/42/38442/1

diff --git 
a/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/NotificationService.java
 
b/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/NotificationService.java
index 6f72d9a..431f76f 100644
--- 
a/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/NotificationService.java
+++ 
b/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/NotificationService.java
@@ -118,6 +118,7 @@
                     for (String subscriber : dbDownSubscribers.split(",")) {
                         new FirstMatchSimpleFilter.FilterEntry(
                                 EventsManager.DATABASE_UNREACHABLE,
+                                null,
                                 false,
                                 EventNotificationMethod.SMTP.getAsString(),
                                 subscriber);
diff --git 
a/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/dao/EventsManager.java
 
b/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/dao/EventsManager.java
index 96de97a..b5bd10a 100644
--- 
a/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/dao/EventsManager.java
+++ 
b/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/dao/EventsManager.java
@@ -92,6 +92,7 @@
                 String eventDownName = eventMap.get(eventUpName);
                 eventSubscribers.add(
                         new FirstMatchSimpleFilter.FilterEntry(eventUpName,
+                                null,
                                 false,
                                 rs.getString("notification_method"),
                                 rs.getString("method_address")));
@@ -99,6 +100,7 @@
                 if (eventDownName != null) {
                     eventSubscribers.add(
                             new 
FirstMatchSimpleFilter.FilterEntry(eventDownName,
+                                    null,
                                     false,
                                     rs.getString("notification_method"),
                                     rs.getString("method_address")));
diff --git 
a/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/filter/FirstMatchSimpleFilter.java
 
b/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/filter/FirstMatchSimpleFilter.java
index 43f54dc..1ec1cb6 100644
--- 
a/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/filter/FirstMatchSimpleFilter.java
+++ 
b/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/filter/FirstMatchSimpleFilter.java
@@ -10,6 +10,7 @@
 import java.util.regex.Pattern;
 
 import org.apache.commons.lang.StringUtils;
+import org.ovirt.engine.core.common.AuditLogSeverity;
 import org.ovirt.engine.core.notifier.transport.Transport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -22,6 +23,10 @@
             "((?<include>include)|(?<exclude>exclude))" +
             ":" +
             "((?<anymsg>\\*)|(?<message>\\w+))" +
+            "(?>" +
+                ":" +
+                "((?<anyseverity>\\*)|(?<severity>\\w+))" +
+            ")?" +
             "(?<recipient>" +
                 "\\(" +
                     "(" +
@@ -75,6 +80,10 @@
                         entry.getEventName().equals(event.getName())
                         ) &&
                         (
+                        entry.getSeverity() == null ||
+                        severityMatches(entry.getSeverity(), 
event.getSeverity(), entry.isExclude())
+                        ) &&
+                        (
                         entry.getRecipient() == null ||
                         entry.getRecipient().equals(recipient)
                         )) {
@@ -92,6 +101,24 @@
                 }
             }
         }
+    }
+
+    private boolean severityMatches(
+            String filterSeverityString,
+            AuditLogSeverity eventSeverity,
+            boolean isExclusion) {
+        // Severity matching works in the opposite way for inclusions and 
exclusions; a filter will
+        // include events of equal-or-greater severity or exclude events of 
lesser-or-equal severity.
+        AuditLogSeverity filterSeverity;
+        try {
+            filterSeverity = AuditLogSeverity.valueOf(filterSeverityString);
+        } catch (IllegalArgumentException e) {
+            log.warn("Severity value '{}' specified in notifier configuration" 
+
+                     " does not match any known severities", 
filterSeverityString);
+            return false;
+        }
+        int cmp = eventSeverity.compareTo(filterSeverity);
+        return isExclusion ? cmp <= 0 : cmp >= 0;
     }
 
     public static List<FilterEntry> parse(String filters) {
@@ -112,6 +139,7 @@
                 ret.add(
                         new FilterEntry(
                                 m.group("anymsg") != null ? null : 
m.group("message"),
+                                m.group("anyseverity") != null ? null : 
m.group("severity"),
                                 m.group("exclude") != null,
                                 m.group("recipient") == null || 
m.group("anyrecipient") != null ? null : new Recipient(
                                         m.group("transport"),
@@ -154,7 +182,8 @@
             }
 
             Recipient that = (Recipient) obj;
-            return (StringUtils.equals(this.transport, that.transport) && 
StringUtils.equals(this.name, that.name));
+            return (StringUtils.equals(this.transport, that.transport)
+                    && StringUtils.equals(this.name, that.name));
         }
 
         @Override
@@ -177,22 +206,29 @@
 
         private final String eventName;
 
+        private final String severity;
+
         private final boolean exclude;
 
         private final Recipient recipient;
 
-        public FilterEntry(String eventName, boolean exclude, Recipient 
recipient) {
+        public FilterEntry(String eventName, String severity, boolean exclude, 
Recipient recipient) {
             this.eventName = eventName;
+            this.severity = severity;
             this.exclude = exclude;
             this.recipient = recipient;
         }
 
-        public FilterEntry(String eventName, boolean exclude, String 
transport, String name) {
-            this(eventName, exclude, new Recipient(transport, name));
+        public FilterEntry(String eventName, String severity, boolean exclude, 
String transport, String name) {
+            this(eventName, severity, exclude, new Recipient(transport, name));
         }
 
         public String getEventName() {
             return eventName;
+        }
+
+        public String getSeverity() {
+            return severity;
         }
 
         public boolean isExclude() {
@@ -207,6 +243,7 @@
         public String toString() {
             return "FilterEntry{" +
                     "eventName='" + eventName + '\'' +
+                    ", severity=" + severity +
                     ", exclude=" + exclude +
                     ", recipient=" + recipient +
                     '}';
diff --git 
a/backend/manager/tools/src/test/java/org/ovirt/engine/core/notifier/filter/FirstMatchSimpleFilterTest.java
 
b/backend/manager/tools/src/test/java/org/ovirt/engine/core/notifier/filter/FirstMatchSimpleFilterTest.java
index 56a322d..871abad 100644
--- 
a/backend/manager/tools/src/test/java/org/ovirt/engine/core/notifier/filter/FirstMatchSimpleFilterTest.java
+++ 
b/backend/manager/tools/src/test/java/org/ovirt/engine/core/notifier/filter/FirstMatchSimpleFilterTest.java
@@ -4,6 +4,7 @@
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.ovirt.engine.core.common.AuditLogSeverity;
 import org.ovirt.engine.core.notifier.dao.DispatchResult;
 import org.ovirt.engine.core.notifier.transport.Observer;
 import org.ovirt.engine.core.notifier.transport.Transport;
@@ -21,19 +22,30 @@
     T smtp;
 
     /*
-     * This replaces the application message representation, the only request 
we have is to have getName() to return the
-     * name based on which we filter.
+     * This replaces the application message representation; the only requests 
we have are getName() to return the
+     * name based on which we filter, and getSeverity() used only in filters 
where the severity is specified.
      */
     private static class E extends AuditLogEvent {
         private String e;
+        private AuditLogSeverity s;
 
         public E(String e) {
+            this(e, null);
+        }
+
+        public E(String e, AuditLogSeverity s) {
             this.e = e;
+            this.s = s;
         }
 
         @Override
         public String getName() {
             return e;
+        }
+
+        @Override
+        public AuditLogSeverity getSeverity() {
+            return s;
         }
     }
 
@@ -116,7 +128,7 @@
         filter.clearFilterEntries();
         filter.addFilterEntries(
                 Collections.singletonList(
-                        new FirstMatchSimpleFilter.FilterEntry("message0", 
false, "smtp", "[email protected]"))
+                        new FirstMatchSimpleFilter.FilterEntry("message0", 
null, false, "smtp", "[email protected]"))
                 );
         filter.processEvent(new E("message0"));
         filter.processEvent(new E("message1"));
@@ -156,13 +168,63 @@
     }
 
     @Test
+    public void testSeverity() throws Exception {
+        String expected1 = "[email protected]";
+        String expected2 = "[email protected]";
+        filter.clearFilterEntries();
+        filter.addFilterEntries(
+                FirstMatchSimpleFilter.parse(
+                        "include:*:WARNING(smtp:" + expected1 + ") " +
+                        "exclude:*(smtp:" + expected1 + ")" +
+                        "exclude:*:WARNING(smtp:" + expected2 + ") " +
+                        "include:*(smtp:" + expected2 + ")"
+                ));
+        filter.processEvent(new E("message1", AuditLogSeverity.NORMAL));
+        filter.processEvent(new E("message2", AuditLogSeverity.WARNING));
+        filter.processEvent(new E("message3", AuditLogSeverity.ERROR));
+        Assert.assertTrue(smtp.getEvents().contains("message2-->" + 
expected1));
+        Assert.assertTrue(smtp.getEvents().contains("message3-->" + 
expected1));
+        Assert.assertTrue(smtp.getEvents().contains("message3-->" + 
expected2));
+        Assert.assertEquals(3, smtp.getEvents().size());
+    }
+
+    @Test
+    public void testSeverityAndEventCombo() throws Exception {
+        // These combinations aren't useful in the real world, but we want 
them to work anyway
+        String expected = "[email protected]";
+        filter.clearFilterEntries();
+        filter.addFilterEntries(
+                FirstMatchSimpleFilter.parse(
+                        "include:normal_message:ERROR(smtp:" + expected + ") " 
+
+                        "include:error_message:NORMAL(smtp:" + expected + ") " 
+
+                        "exclude:*"
+                ));
+        filter.processEvent(new E("normal_message", AuditLogSeverity.NORMAL));
+        filter.processEvent(new E("error_message", AuditLogSeverity.ERROR));
+        Assert.assertTrue(smtp.getEvents().contains("error_message-->" + 
expected));
+        Assert.assertEquals(1, smtp.getEvents().size());
+    }
+
+    @Test
+    public void testNonExistingSeverity() throws Exception {
+        // A filter tuple with invalid severity should be ignored
+        filter.clearFilterEntries();
+        filter.addFilterEntries(
+                FirstMatchSimpleFilter.parse(
+                        
"include:message1:_badSeverityTest_(smtp:[email protected]) exclude:*")
+        );
+        filter.processEvent(new E("message1", AuditLogSeverity.ALERT));
+        Assert.assertTrue(smtp.getEvents().isEmpty());
+    }
+
+    @Test
     public void testAll() throws Exception {
         filter.clearFilterEntries();
         filter.addFilterEntries(Collections.singletonList(
-                new FirstMatchSimpleFilter.FilterEntry("kuku", false, "snmp", 
"pupu"))
+                new FirstMatchSimpleFilter.FilterEntry("kuku", null, false, 
"snmp", "pupu"))
                 );
         filter.addFilterEntries(Collections.singletonList(
-                new FirstMatchSimpleFilter.FilterEntry("kuku", false, "smtp", 
"pupu"))
+                new FirstMatchSimpleFilter.FilterEntry("kuku", null, false, 
"smtp", "pupu"))
                 );
         filter.addFilterEntries(
                 FirstMatchSimpleFilter.parse(
diff --git 
a/packaging/services/ovirt-engine-notifier/ovirt-engine-notifier.conf.in 
b/packaging/services/ovirt-engine-notifier/ovirt-engine-notifier.conf.in
index d7e13ad..dfca4a3 100644
--- a/packaging/services/ovirt-engine-notifier/ovirt-engine-notifier.conf.in
+++ b/packaging/services/ovirt-engine-notifier/ovirt-engine-notifier.conf.in
@@ -119,24 +119,31 @@
 # Filter syntax
 #
 # FILTER=[PATTERN ...]
-# PATTERN=include|exclude:event[(subscriber)]
+# PATTERN=include|exclude:event[:severity][(subscriber)]
 #
 # Filter logic
 #
-# Each (event E, subscriber S) pair is checked against each
+# Each (event E, severity, subscriber S) tuple is checked against each
 # include/exclude pattern in turn, and the first pattern match is acted upon:
 # if it is an include pattern then E is sent to S;
 # if it is an exclude pattern then E is skipped for S;
 #
 # The event '*' matches everything.
+# A missing severity and the severity '*' matches everything.
 # A missing '(subscriber)' matches all subscribers and should only be used for 
excludes.
 #
 # Message constants can be found at:
 # @ENGINE_DOC@/AuditLogMessages.properties
 #
+# Valid severity values in increasing order of severity include:
+#   'NORMAL', 'WARNING', 'ERROR', 'ALERT'
+# An inclusion filter with a given severity will match all events of 
greater-or-equal severity;
+# an exclusion filter with a given severity will match all events of 
lesser-or-equal severity.
+#
 # examples:
 # FILTER="include:VDC_START(smtp:[email protected]) ${FILTER}"
 # FILTER="exclude:VDC_START include:*(smtp:[email protected]) ${FILTER}"
+# FILTER="include:*:ERROR(smtp:[email protected]) ${FILTER}"
 #
 # The final filter list contains FILTER  as well as 'event_subscriber' table 
records.
 # database records are considered first.


-- 
To view, visit https://gerrit.ovirt.org/38442
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia8abc34d56f1ede2fb51daf71dee293d08f198a3
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Greg Padgett <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to