cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wid...@apache.org
Subject [23/52] [abbrv] git commit: updated refs/heads/qemu-img to 44197a0
Date Sat, 30 Mar 2013 09:58:52 GMT
CLOUDSTACK-712: Feature Syslog Enhancements

Signed-off-by: Anshul Gangwar <anshul.gangwar@citrix.com>
Signed-off-by: Sateesh Chodapuneedi <sateesh@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/6a7156ad
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/6a7156ad
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/6a7156ad

Branch: refs/heads/qemu-img
Commit: 6a7156ad9af6ca173c0b685d69d5724d91d0a401
Parents: 2c176ab
Author: Anshul Gangwar <anshul.gangwar@citrix.com>
Authored: Wed Mar 6 14:11:47 2013 +0530
Committer: Sateesh Chodapuneedi <sateesh@apache.org>
Committed: Fri Mar 29 09:53:05 2013 +0530

----------------------------------------------------------------------
 client/pom.xml                                     |    5 +
 client/tomcatconf/log4j-cloud.xml.in               |   15 +
 plugins/alert-handlers/syslog-alerts/pom.xml       |   40 ++
 .../cloudstack/syslog/AlertsSyslogAppender.java    |  336 +++++++++++++++
 .../syslog/AlertsSyslogAppenderTest.java           |   61 +++
 plugins/pom.xml                                    |    1 +
 6 files changed, 458 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6a7156ad/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index 23892e1..61cda76 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -67,6 +67,11 @@
     </dependency>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-plugin-syslog-alerts</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-plugin-snmp-alerts</artifactId>
       <version>${project.version}</version>
     </dependency>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6a7156ad/client/tomcatconf/log4j-cloud.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/log4j-cloud.xml.in b/client/tomcatconf/log4j-cloud.xml.in
index ce4079f..0e7f004 100755
--- a/client/tomcatconf/log4j-cloud.xml.in
+++ b/client/tomcatconf/log4j-cloud.xml.in
@@ -74,6 +74,20 @@ under the License.
          <param name="ConversionPattern" value="%-5p [%c{3}] (%t:%x) %m%n"/>
       </layout>
    </appender>
+
+   <!-- ============================== -->
+   <!-- Append alerts to the syslog if it is configured -->
+   <!-- ============================== -->
+
+   <appender name="ALERTSYSLOG" class="org.apache.cloudstack.syslog.AlertsSyslogAppender">
+      <param name="Threshold" value="WARN"/>
+      <param name="SyslogHosts" value=""/>
+      <param name="Facility" value="LOCAL6"/>
+      <layout class="org.apache.log4j.PatternLayout">
+         <param name="ConversionPattern" value="%-5p [%c{3}] (%t:%x) %m%n"/>
+      </layout>
+   </appender>
+
    <!-- ============================== -->
    <!-- send alert warnings+ as the SNMP trap if it is configured! -->
    <!-- ============================== -->
@@ -166,6 +180,7 @@ under the License.
       <appender-ref ref="CONSOLE"/>
       <appender-ref ref="FILE"/>
       <appender-ref ref="SNMP"/>
+      <appender-ref ref="ALERTSYSLOG"/>
    </logger>
 
    <!-- ======================= -->

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6a7156ad/plugins/alert-handlers/syslog-alerts/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/alert-handlers/syslog-alerts/pom.xml b/plugins/alert-handlers/syslog-alerts/pom.xml
new file mode 100644
index 0000000..21aa54a
--- /dev/null
+++ b/plugins/alert-handlers/syslog-alerts/pom.xml
@@ -0,0 +1,40 @@
+<!--
+  ~ Licensed to the 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.  The 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
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>cloudstack-plugins</artifactId>
+    <groupId>org.apache.cloudstack</groupId>
+    <version>4.2.0-SNAPSHOT</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <name>Apache CloudStack Plugin - Syslog Alerts</name>
+  <artifactId>cloud-plugin-syslog-alerts</artifactId>
+
+  <dependencies>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <version>${cs.log4j.version}</version>
+    </dependency>
+  </dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6a7156ad/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java
----------------------------------------------------------------------
diff --git a/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java
b/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java
new file mode 100644
index 0000000..d2f2565
--- /dev/null
+++ b/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java
@@ -0,0 +1,336 @@
+// Licensed to the 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.  The 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 org.apache.cloudstack.syslog;
+
+import com.cloud.utils.net.NetUtils;
+import org.apache.log4j.AppenderSkeleton;
+import org.apache.log4j.net.SyslogAppender;
+import org.apache.log4j.spi.LoggingEvent;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+public class AlertsSyslogAppender extends AppenderSkeleton {
+    String _syslogHosts = null;
+    String _delimiter = ",";
+    List<String> _syslogHostsList = null;
+    List<SyslogAppender> _syslogAppenders = null;
+    private String _facility;
+    private String _pairDelimiter = "//";
+    private String _keyValueDelimiter = "::";
+    private int alertType = -1;
+    private long dataCenterId = 0;
+    private long podId = 0;
+    private long clusterId = 0;
+    private String sysMessage = null;
+    public static final int LENGTH_OF_STRING_MESSAGE_AND_KEY_VALUE_DELIMITER = 9;
+    public static final int LENGTH_OF_STRING_MESSAGE = 8;
+    public static final String MESSAGE_DELIMITER_STRING = "   ";
+    //add the alertType in this array it its level needs to be set to critical
+    private static final int[] criticalAlerts = {7, 8, 9, 10, 11, 12, 13, 15, 16, 19, 20};
+    private static final Map<Integer, String> alertsMap;
+
+    static {
+        Map<Integer, String> aMap = new HashMap<Integer, String>(27);
+        aMap.put(0, "availableMemory");
+        aMap.put(1, "availableCpu");
+        aMap.put(2, "availableStorage");
+        aMap.put(3, "remainingStorageAllocated");
+        aMap.put(4, "unallocatedVirtualNetworkpublicIp");
+        aMap.put(5, "unallocatedPrivateIp");
+        aMap.put(6, "availableSecondaryStorage");
+        aMap.put(7, "host");
+        aMap.put(8, "userVmState");
+        aMap.put(9, "domainRouterVmState ");
+        aMap.put(10, "consoleProxyVmState");
+        aMap.put(11, "routingConnection");
+        aMap.put(12, "storageIssueSystemVms");
+        aMap.put(13, "usageServerStatus");
+        aMap.put(14, "managementNode");
+        aMap.put(15, "domainRouterMigrate");
+        aMap.put(16, "consoleProxyMigrate");
+        aMap.put(17, "userVmMigrate");
+        aMap.put(18, "unallocatedVlan");
+        aMap.put(19, "ssvmStopped");
+        aMap.put(20, "usageServerResult");
+        aMap.put(21, "storageDelete");
+        aMap.put(22, "updateResourceCount");
+        aMap.put(23, "usageSanityResult");
+        aMap.put(24, "unallocatedDirectAttachedPublicIp");
+        aMap.put(25, "unallocatedLocalStorage");
+        aMap.put(26, "resourceLimitExceeded");
+
+        alertsMap = Collections.unmodifiableMap(aMap);
+    }
+
+    @Override
+    protected void append(LoggingEvent event) {
+        if (!isAsSevereAsThreshold(event.getLevel())) {
+            return;
+        }
+
+        if (_syslogAppenders != null && !_syslogAppenders.isEmpty()) {
+            try {
+                String logMessage = event.getRenderedMessage();
+                if (logMessage.contains("alertType") && logMessage.contains("message"))
{
+                    parseMessage(logMessage);
+                    String syslogMessage = createSyslogMessage();
+
+                    LoggingEvent syslogEvent = new LoggingEvent(event.getFQNOfLoggerClass(),
event.getLogger(),
+                        event.getLevel(), syslogMessage, null);
+
+                    for (SyslogAppender syslogAppender : _syslogAppenders) {
+                        syslogAppender.append(syslogEvent);
+                    }
+                }
+            } catch (Exception e) {
+                errorHandler.error(e.getMessage());
+            }
+        }
+    }
+
+    @Override
+    synchronized public void close() {
+        for (SyslogAppender syslogAppender : _syslogAppenders) {
+            syslogAppender.close();
+        }
+    }
+
+    @Override
+    public boolean requiresLayout() {
+        return true;
+    }
+
+    void setSyslogAppenders() {
+        if (_syslogAppenders == null) {
+            _syslogAppenders = new ArrayList<SyslogAppender>();
+        }
+
+        if (_syslogHosts == null || _syslogHosts.trim().isEmpty()) {
+            reset();
+            return;
+        }
+
+        _syslogHostsList = parseSyslogHosts(_syslogHosts);
+
+        if (!validateIpAddresses()) {
+            reset();
+            errorHandler.error(" Invalid format for the IP Addresses parameter ");
+            return;
+        }
+
+        for (String syslogHost : _syslogHostsList) {
+            _syslogAppenders.add(new SyslogAppender(getLayout(), syslogHost, SyslogAppender.getFacility(_facility)));
+        }
+    }
+
+    private List<String> parseSyslogHosts(String syslogHosts) {
+        List<String> result = new ArrayList<String>();
+
+        final StringTokenizer tokenizer = new StringTokenizer(syslogHosts, _delimiter);
+        while (tokenizer.hasMoreTokens()) {
+            result.add(tokenizer.nextToken().trim());
+        }
+        return result;
+    }
+
+    private boolean validateIpAddresses() {
+        for (String ipAddress : _syslogHostsList) {
+            if (ipAddress.trim().equalsIgnoreCase("localhost")) {
+                continue;
+            }
+            if (!NetUtils.isValidIp(ipAddress)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    void parseMessage(String logMessage) {
+            final StringTokenizer messageSplitter = new StringTokenizer(logMessage, _pairDelimiter);
+            while (messageSplitter.hasMoreTokens()) {
+                final String pairToken = messageSplitter.nextToken();
+                final StringTokenizer pairSplitter = new StringTokenizer(pairToken, _keyValueDelimiter);
+                String keyToken;
+                String valueToken;
+
+                if (pairSplitter.hasMoreTokens()) {
+                    keyToken = pairSplitter.nextToken().trim();
+                } else {
+                    break;
+                }
+
+                if (pairSplitter.hasMoreTokens()) {
+                    valueToken = pairSplitter.nextToken().trim();
+                } else {
+                    break;
+                }
+
+                if (keyToken.equalsIgnoreCase("alertType") && !valueToken.equalsIgnoreCase("null"))
{
+                    alertType = Short.parseShort(valueToken);
+                } else if (keyToken.equalsIgnoreCase("dataCenterId") && !valueToken.equalsIgnoreCase("null"))
{
+                    dataCenterId = Long.parseLong(valueToken);
+                } else if (keyToken.equalsIgnoreCase("podId") && !valueToken.equalsIgnoreCase("null"))
{
+                    podId = Long.parseLong(valueToken);
+                } else if (keyToken.equalsIgnoreCase("clusterId") && !valueToken.equalsIgnoreCase("null"))
{
+                    clusterId = Long.parseLong(valueToken);
+                } else if (keyToken.equalsIgnoreCase("message") && !valueToken.equalsIgnoreCase("null"))
{
+                    sysMessage = getSyslogMessage(logMessage);
+                }
+            }
+    }
+
+    String createSyslogMessage() {
+        StringBuilder message = new StringBuilder();
+        message.append(severityOfAlert(alertType)).append(MESSAGE_DELIMITER_STRING);
+        InetAddress ip;
+        try {
+            ip = InetAddress.getLocalHost();
+        } catch (UnknownHostException e) {
+            ip = null;
+        }
+
+        if (ip != null) {
+            message.append(ip.getHostName()).append(MESSAGE_DELIMITER_STRING);
+        } else {
+            message.append("unknown" + MESSAGE_DELIMITER_STRING);
+        }
+
+        if (alertType > 0) {
+            message.append("alertType").append(_keyValueDelimiter).append(" ").append(alertsMap.get(alertType))
+                .append(MESSAGE_DELIMITER_STRING);
+            if (dataCenterId != 0) {
+                message.append("dataCenterId").append(_keyValueDelimiter).append(" ").append(dataCenterId)
+                    .append(MESSAGE_DELIMITER_STRING);
+            }
+
+            if (podId != 0) {
+                message.append("podId").append(_keyValueDelimiter).append(" ").append(podId)
+                    .append(MESSAGE_DELIMITER_STRING);
+            }
+
+            if (clusterId != 0) {
+                message.append("clusterId").append(_keyValueDelimiter).append(" ").append(clusterId)
+                    .append(MESSAGE_DELIMITER_STRING);
+            }
+
+            if (sysMessage != null) {
+                message.append("message").append(_keyValueDelimiter).append(" ").append(sysMessage);
+            } else {
+                errorHandler.error(" What is the use of alert without message ");
+            }
+        } else {
+            errorHandler.error(" Invalid alert Type ");
+        }
+
+        return message.toString();
+    }
+
+    private String getSyslogMessage(String message) {
+        int lastIndexOfKeyValueDelimiter = message.lastIndexOf(_keyValueDelimiter);
+        int lastIndexOfMessageInString = message.lastIndexOf("message");
+
+        if (lastIndexOfKeyValueDelimiter - lastIndexOfMessageInString <=
+            LENGTH_OF_STRING_MESSAGE_AND_KEY_VALUE_DELIMITER) {
+            return message.substring(lastIndexOfKeyValueDelimiter + _keyValueDelimiter.length()).trim();
+        } else if (lastIndexOfMessageInString < lastIndexOfKeyValueDelimiter) {
+            return message.substring(
+                lastIndexOfMessageInString + _keyValueDelimiter.length() + LENGTH_OF_STRING_MESSAGE).trim();
+        }
+
+        return message.substring(message.lastIndexOf("message" + _keyValueDelimiter) +
+            LENGTH_OF_STRING_MESSAGE_AND_KEY_VALUE_DELIMITER).trim();
+    }
+
+    private void reset() {
+        _syslogAppenders.clear();
+    }
+
+    public void setFacility(String facility) {
+        if (facility == null) {
+            return;
+        }
+
+        this._facility = facility;
+        if (_syslogAppenders != null && !_syslogAppenders.isEmpty()) {
+            for (SyslogAppender syslogAppender : _syslogAppenders) {
+                syslogAppender.setFacility(facility);
+            }
+        }
+    }
+
+    private String severityOfAlert(int alertType) {
+        if (isCritical(alertType)) {
+            return "CRITICAL";
+        } else {
+            return "WARN";
+        }
+    }
+
+    private boolean isCritical(int alertType) {
+        for (int type : criticalAlerts) {
+            if (type == alertType) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public String getFacility() {
+        return _facility;
+    }
+
+    public String getSyslogHosts() {
+        return _syslogHosts;
+    }
+
+    public void setSyslogHosts(String syslogHosts) {
+        this._syslogHosts = syslogHosts;
+        this.setSyslogAppenders();
+    }
+
+    public String getDelimiter() {
+        return _delimiter;
+    }
+
+    public void setDelimiter(String delimiter) {
+        this._delimiter = delimiter;
+    }
+
+    public String getPairDelimiter() {
+        return _pairDelimiter;
+    }
+
+    public void setPairDelimiter(String pairDelimiter) {
+        this._pairDelimiter = pairDelimiter;
+    }
+
+    public String getKeyValueDelimiter() {
+        return _keyValueDelimiter;
+    }
+
+    public void setKeyValueDelimiter(String keyValueDelimiter) {
+        this._keyValueDelimiter = keyValueDelimiter;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6a7156ad/plugins/alert-handlers/syslog-alerts/test/org/apache/cloudstack/syslog/AlertsSyslogAppenderTest.java
----------------------------------------------------------------------
diff --git a/plugins/alert-handlers/syslog-alerts/test/org/apache/cloudstack/syslog/AlertsSyslogAppenderTest.java
b/plugins/alert-handlers/syslog-alerts/test/org/apache/cloudstack/syslog/AlertsSyslogAppenderTest.java
new file mode 100644
index 0000000..68585ee
--- /dev/null
+++ b/plugins/alert-handlers/syslog-alerts/test/org/apache/cloudstack/syslog/AlertsSyslogAppenderTest.java
@@ -0,0 +1,61 @@
+// Licensed to the 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.  The 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 org.apache.cloudstack.syslog;
+
+import org.apache.log4j.PatternLayout;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.naming.ConfigurationException;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+public class AlertsSyslogAppenderTest {
+    AlertsSyslogAppender _appender = new AlertsSyslogAppender();
+
+    @Before
+    public void setUp() throws ConfigurationException {
+        _appender.setLayout(new PatternLayout("%-5p [%c{3}] (%t:%x) %m%n"));
+        _appender.setFacility("LOCAL6");
+    }
+
+    @Test
+    public void setSyslogAppendersTest() {
+        _appender.setSyslogHosts("10.1.1.1,10.1.1.2");
+        assertEquals(" error Syslog Appenders list size not as expected ", 2, _appender._syslogAppenders.size());
+    }
+
+    @Test
+    public void setSyslogAppendersNegativeTest() {
+        //setting invalid IP for Syslog Hosts
+        _appender.setSyslogHosts("10.1.1.");
+        assertTrue(" list was expected to be empty", _appender._syslogAppenders.isEmpty());
+    }
+
+    @Test
+    public void appendTest() {
+        String message = "alertType:: 14 // dataCenterId:: 0 // podId:: 0 // clusterId::
null // message:: Management" +
+            " server node 127.0.0.1 is up";
+        _appender.parseMessage(message);
+        String createdMessage =  _appender.createSyslogMessage();
+        assertTrue(" message is not as expected ", createdMessage.contains("alertType:: managementNode"
+
+            AlertsSyslogAppender.MESSAGE_DELIMITER_STRING + "message:: Management server
node 127.0.0.1 is up"));
+        assertTrue("severity level not as expected ", createdMessage.contains("WARN"));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6a7156ad/plugins/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/pom.xml b/plugins/pom.xml
index 39d9907..d7e8deb 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -59,6 +59,7 @@
     <module>storage/volume/solidfire</module>
     <module>storage/volume/default</module>
     <module>alert-handlers/snmp-alerts</module>
+    <module>alert-handlers/syslog-alerts</module>
   </modules>
 
   <dependencies>


Mime
View raw message