Skip to content

Commit 61754cd

Browse files
anshulgangwarSateesh Chodapuneedi
authored andcommitted
CLOUDSTACK-680: Feature SNMP Alerts support in CloudStack
Signed-off-by: Anshul Gangwar <anshul.gangwar@citrix.com> Signed-off-by: Sateesh Chodapuneedi <sateesh@apache.org>
1 parent e1c72bc commit 61754cd

14 files changed

Lines changed: 843 additions & 24 deletions

File tree

client/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@
6565
<artifactId>cloud-plugin-network-nvp</artifactId>
6666
<version>${project.version}</version>
6767
</dependency>
68+
<dependency>
69+
<groupId>org.apache.cloudstack</groupId>
70+
<artifactId>cloud-plugin-snmp-alerts</artifactId>
71+
<version>${project.version}</version>
72+
</dependency>
6873
<dependency>
6974
<groupId>org.apache.cloudstack</groupId>
7075
<artifactId>cloud-plugin-network-ovs</artifactId>

client/tomcatconf/log4j-cloud.xml.in

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,20 @@ under the License.
7474
<param name="ConversionPattern" value="%-5p [%c{3}] (%t:%x) %m%n"/>
7575
</layout>
7676
</appender>
77+
<!-- ============================== -->
78+
<!-- send alert warnings+ as the SNMP trap if it is configured! -->
79+
<!-- ============================== -->
80+
81+
<appender name="SNMP" class="org.apache.cloudstack.alert.snmp.SnmpTrapAppender">
82+
<param name="Threshold" value="WARN"/>
83+
<param name="SnmpManagerIpAddresses" value=""/>
84+
<param name="SnmpManagerPorts" value=""/>
85+
<param name="SnmpManagerCommunities" value=""/>
86+
<layout class="org.apache.cloudstack.alert.snmp.SnmpEnhancedPatternLayout">
87+
<param name="PairDelimiter" value="//"/>
88+
<param name="KeyValueDelimiter" value="::"/>
89+
</layout>
90+
</appender>
7791

7892
<!-- ============================== -->
7993
<!-- Append messages to the console -->
@@ -142,6 +156,17 @@ under the License.
142156
<appender-ref ref="AWSAPI"/>
143157
</logger>
144158

159+
<!-- ============================== -->
160+
<!-- Add or remove these logger for SNMP, this logger is for SNMP alerts plugin -->
161+
<!-- ============================== -->
162+
163+
<logger name="org.apache.cloudstack.alerts" additivity="false">
164+
<level value="WARN"/>
165+
<appender-ref ref="SYSLOG"/>
166+
<appender-ref ref="CONSOLE"/>
167+
<appender-ref ref="FILE"/>
168+
<appender-ref ref="SNMP"/>
169+
</logger>
145170

146171
<!-- ======================= -->
147172
<!-- Setup the Root category -->

core/src/com/cloud/alert/AlertManager.java

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,27 @@ public interface AlertManager extends Manager {
2727
public static final short ALERT_TYPE_VIRTUAL_NETWORK_PUBLIC_IP = CapacityVO.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP;
2828
public static final short ALERT_TYPE_PRIVATE_IP = CapacityVO.CAPACITY_TYPE_PRIVATE_IP;
2929
public static final short ALERT_TYPE_SECONDARY_STORAGE = CapacityVO.CAPACITY_TYPE_SECONDARY_STORAGE;
30-
public static final short ALERT_TYPE_HOST = 6;
31-
public static final short ALERT_TYPE_USERVM = 7;
32-
public static final short ALERT_TYPE_DOMAIN_ROUTER = 8;
33-
public static final short ALERT_TYPE_CONSOLE_PROXY = 9;
34-
public static final short ALERT_TYPE_ROUTING = 10; // lost connection to default route (to the gateway)
35-
public static final short ALERT_TYPE_STORAGE_MISC = 11; // lost connection to default route (to the gateway)
36-
public static final short ALERT_TYPE_USAGE_SERVER = 12; // lost connection to default route (to the gateway)
37-
public static final short ALERT_TYPE_MANAGMENT_NODE = 13; // lost connection to default route (to the gateway)
38-
public static final short ALERT_TYPE_DOMAIN_ROUTER_MIGRATE = 14;
39-
public static final short ALERT_TYPE_CONSOLE_PROXY_MIGRATE = 15;
40-
public static final short ALERT_TYPE_USERVM_MIGRATE = 16;
41-
public static final short ALERT_TYPE_VLAN = 17;
42-
public static final short ALERT_TYPE_SSVM = 18;
43-
public static final short ALERT_TYPE_USAGE_SERVER_RESULT = 19; // Usage job result
44-
public static final short ALERT_TYPE_STORAGE_DELETE = 20;
45-
public static final short ALERT_TYPE_UPDATE_RESOURCE_COUNT = 21; // Generated when we fail to update the resource count
46-
public static final short ALERT_TYPE_USAGE_SANITY_RESULT = 22;
47-
public static final short ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP = 23;
48-
public static final short ALERT_TYPE_LOCAL_STORAGE = 24;
49-
public static final short ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED = 25; // Generated when the resource limit exceeds the limit. Currently used for recurring snapshots only
30+
public static final short ALERT_TYPE_HOST = 7;
31+
public static final short ALERT_TYPE_USERVM = 8;
32+
public static final short ALERT_TYPE_DOMAIN_ROUTER = 9;
33+
public static final short ALERT_TYPE_CONSOLE_PROXY = 10;
34+
public static final short ALERT_TYPE_ROUTING = 11; // lost connection to default route (to the gateway)
35+
public static final short ALERT_TYPE_STORAGE_MISC = 12; // lost connection to default route (to the gateway)
36+
public static final short ALERT_TYPE_USAGE_SERVER = 13; // lost connection to default route (to the gateway)
37+
public static final short ALERT_TYPE_MANAGMENT_NODE = 14; // lost connection to default route (to the gateway)
38+
public static final short ALERT_TYPE_DOMAIN_ROUTER_MIGRATE = 15;
39+
public static final short ALERT_TYPE_CONSOLE_PROXY_MIGRATE = 16;
40+
public static final short ALERT_TYPE_USERVM_MIGRATE = 17;
41+
public static final short ALERT_TYPE_VLAN = 18;
42+
public static final short ALERT_TYPE_SSVM = 19;
43+
public static final short ALERT_TYPE_USAGE_SERVER_RESULT = 20; // Usage job result
44+
public static final short ALERT_TYPE_STORAGE_DELETE = 21;
45+
public static final short ALERT_TYPE_UPDATE_RESOURCE_COUNT = 22; // Generated when we fail to update the resource
46+
// count
47+
public static final short ALERT_TYPE_USAGE_SANITY_RESULT = 23;
48+
public static final short ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP = 24;
49+
public static final short ALERT_TYPE_LOCAL_STORAGE = 25;
50+
public static final short ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED = 26; // Generated when the resource limit exceeds the limit. Currently used for recurring snapshots only
5051

5152

5253
void clearAlert(short alertType, long dataCenterId, long podId);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!--
2+
~ Licensed to the Apache Software Foundation (ASF) under one
3+
~ or more contributor license agreements. See the NOTICE file
4+
~ distributed with this work for additional information
5+
~ regarding copyright ownership. The ASF licenses this file
6+
~ to you under the Apache License, Version 2.0 (the
7+
~ "License"); you may not use this file except in compliance
8+
~ with the License. You may obtain a copy of the License at
9+
~
10+
~ http://www.apache.org/licenses/LICENSE-2.0
11+
~
12+
~ Unless required by applicable law or agreed to in writing,
13+
~ software distributed under the License is distributed on an
14+
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
~ KIND, either express or implied. See the License for the
16+
~ specific language governing permissions and limitations
17+
~ under the License
18+
-->
19+
<project xmlns="http://maven.apache.org/POM/4.0.0"
20+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
21+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
22+
<parent>
23+
<artifactId>cloudstack-plugins</artifactId>
24+
<groupId>org.apache.cloudstack</groupId>
25+
<version>4.2.0-SNAPSHOT</version>
26+
<relativePath>../../pom.xml</relativePath>
27+
</parent>
28+
<modelVersion>4.0.0</modelVersion>
29+
<name>Apache CloudStack Plugin - SNMP Alerts</name>
30+
<artifactId>cloud-plugin-snmp-alerts</artifactId>
31+
32+
<dependencies>
33+
<dependency>
34+
<groupId>org.apache.servicemix.bundles</groupId>
35+
<artifactId>org.apache.servicemix.bundles.snmp4j</artifactId>
36+
<version>2.1.0_1</version>
37+
</dependency>
38+
<dependency>
39+
<groupId>log4j</groupId>
40+
<artifactId>log4j</artifactId>
41+
<version>${cs.log4j.version}</version>
42+
</dependency>
43+
</dependencies>
44+
45+
</project>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License
17+
18+
package org.apache.cloudstack.alert.snmp;
19+
20+
/**
21+
* <p/>
22+
* IMPORTANT
23+
* <p/>
24+
* These OIDs are based on <b>CS-ROOT-MIB</b> MIB file. If there is any change in MIB file
25+
* then that should be reflected in this file also *
26+
* <br/><br/>
27+
* suffix 2 due to conflict with SnmpConstants class of snmp4j
28+
*/
29+
public class CsSnmpConstants {
30+
public static final String CLOUDSTACK = "1.3.6.1.4.1.18060.15";
31+
32+
public static final String OBJECTS_PREFIX = CLOUDSTACK + ".1.1.";
33+
34+
public static final String TRAPS_PREFIX = CLOUDSTACK + ".1.2.0.";
35+
36+
public static final String DATA_CENTER_ID = OBJECTS_PREFIX + 1;
37+
38+
public static final String POD_ID = OBJECTS_PREFIX + 2;
39+
40+
public static final String CLUSTER_ID = OBJECTS_PREFIX + 3;
41+
42+
public static final String MESSAGE = OBJECTS_PREFIX + 4;
43+
44+
public static final String GENERATION_TIME = OBJECTS_PREFIX + 5;
45+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License
17+
18+
package org.apache.cloudstack.alert.snmp;
19+
20+
import org.apache.log4j.EnhancedPatternLayout;
21+
import org.apache.log4j.spi.LoggingEvent;
22+
23+
import java.util.Date;
24+
import java.util.StringTokenizer;
25+
26+
public class SnmpEnhancedPatternLayout extends EnhancedPatternLayout {
27+
private String _pairDelimiter = "//";
28+
private String _keyValueDelimiter = "::";
29+
30+
private static final int LENGTH_OF_STRING_MESSAGE_AND_KEY_VALUE_DELIMITER = 9;
31+
private static final int LENGTH_OF_STRING_MESSAGE = 8;
32+
33+
public String getKeyValueDelimeter() {
34+
return _keyValueDelimiter;
35+
}
36+
37+
public void setKeyValueDelimiter(String keyValueDelimiter) {
38+
this._keyValueDelimiter = keyValueDelimiter;
39+
}
40+
41+
public String getPairDelimiter() {
42+
return _pairDelimiter;
43+
}
44+
45+
public void setPairDelimiter(String pairDelimiter) {
46+
this._pairDelimiter = pairDelimiter;
47+
}
48+
49+
public SnmpTrapInfo parseEvent(LoggingEvent event) {
50+
SnmpTrapInfo snmpTrapInfo = null;
51+
52+
final String message = event.getRenderedMessage();
53+
if (message.contains("alertType") && message.contains("message")) {
54+
snmpTrapInfo = new SnmpTrapInfo();
55+
final StringTokenizer messageSplitter = new StringTokenizer(message, _pairDelimiter);
56+
while (messageSplitter.hasMoreTokens()) {
57+
final String pairToken = messageSplitter.nextToken();
58+
final StringTokenizer pairSplitter = new StringTokenizer(pairToken, _keyValueDelimiter);
59+
String keyToken;
60+
String valueToken;
61+
62+
if (pairSplitter.hasMoreTokens()) {
63+
keyToken = pairSplitter.nextToken().trim();
64+
} else {
65+
break;
66+
}
67+
68+
if (pairSplitter.hasMoreTokens()) {
69+
valueToken = pairSplitter.nextToken().trim();
70+
} else {
71+
break;
72+
}
73+
74+
if (keyToken.equalsIgnoreCase("alertType") && !valueToken.equalsIgnoreCase("null")) {
75+
snmpTrapInfo.setAlertType(Short.parseShort(valueToken));
76+
} else if (keyToken.equalsIgnoreCase("dataCenterId") && !valueToken.equalsIgnoreCase("null")) {
77+
snmpTrapInfo.setDataCenterId(Long.parseLong(valueToken));
78+
} else if (keyToken.equalsIgnoreCase("podId") && !valueToken.equalsIgnoreCase("null")) {
79+
snmpTrapInfo.setPodId(Long.parseLong(valueToken));
80+
} else if (keyToken.equalsIgnoreCase("clusterId") && !valueToken.equalsIgnoreCase("null")) {
81+
snmpTrapInfo.setClusterId(Long.parseLong(valueToken));
82+
} else if (keyToken.equalsIgnoreCase("message") && !valueToken.equalsIgnoreCase("null")) {
83+
snmpTrapInfo.setMessage(getSnmpMessage(message));
84+
}
85+
}
86+
87+
snmpTrapInfo.setGenerationTime(new Date(event.getTimeStamp()));
88+
}
89+
return snmpTrapInfo;
90+
}
91+
92+
private String getSnmpMessage(String message) {
93+
int lastIndexOfKeyValueDelimiter = message.lastIndexOf(_keyValueDelimiter);
94+
int lastIndexOfMessageInString = message.lastIndexOf("message");
95+
96+
if (lastIndexOfKeyValueDelimiter - lastIndexOfMessageInString <=
97+
LENGTH_OF_STRING_MESSAGE_AND_KEY_VALUE_DELIMITER) {
98+
return message.substring(lastIndexOfKeyValueDelimiter + _keyValueDelimiter.length()).trim();
99+
} else if (lastIndexOfMessageInString < lastIndexOfKeyValueDelimiter) {
100+
return message.substring(
101+
lastIndexOfMessageInString + _keyValueDelimiter.length() + LENGTH_OF_STRING_MESSAGE).trim();
102+
}
103+
104+
return message.substring(message.lastIndexOf("message" + _keyValueDelimiter) +
105+
LENGTH_OF_STRING_MESSAGE_AND_KEY_VALUE_DELIMITER).trim();
106+
}
107+
}

0 commit comments

Comments
 (0)