├── .classpath ├── .gitignore ├── .project ├── .settings ├── org.eclipse.jdt.core.prefs └── org.eclipse.ltk.core.refactoring.prefs ├── LICENSE ├── README.md ├── build.xml ├── config ├── newrelic.json ├── plugin.json.aix ├── plugin.json.linux ├── plugin.json.osx ├── plugin.json.solaris_10 └── plugin.json.solaris_11 ├── dist └── newrelic_unix_plugin.tar.gz ├── etc └── ibm_jsse.java.security ├── hashbang.png ├── img └── you_need_to_upgrade.png ├── lib ├── json-simple-1.1.1.jar └── metrics_publish-2.0.1.jar ├── plugin_jar.jardesc ├── pluginctl.sh └── src └── com └── chocolatefactory └── newrelic └── plugins ├── unix ├── AIXMetrics.java ├── LinuxMetrics.java ├── Main.java ├── OSXMetrics.java ├── SolarisMetrics.java ├── UnixAgent.java ├── UnixAgentFactory.java └── UnixMetrics.java └── utils ├── CommandMetricUtils.java ├── MetricDetail.java └── MetricOutput.java /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/jar/* 2 | /bin/tar/* 3 | /bin/classes/* 4 | /.settings/* 5 | *.class 6 | *.log 7 | dist/newrelic_unix_plugin/** 8 | 9 | **/.DS_Store 10 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | newrelic_unix_plugin 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.5 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.source=1.5 13 | -------------------------------------------------------------------------------- /.settings/org.eclipse.ltk.core.refactoring.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2015 The Chocolate Factory 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # New Relic Plugin for Unix 2 | ## System-Level Montoring for AIX, Linux, Mac OS X & Solaris/SunOS 3 | 4 | # This project has been DEPRECATED in favor of Unix Infra Monitor, which reports to NR Insights: https://github.com/newrelic/newrelic-unix-monitor 5 | 6 | ### Download the plugin here: [newrelic_unix_plugin.tar.gz](https://github.com/sschwartzman/newrelic-unix-plugin/blob/master/dist/newrelic_unix_plugin.tar.gz?raw=true) 7 | 8 | ### What's new in V3.6? 9 | 10 | * Fixed pluginctl.sh (now works on Solaris!) 11 | * Changed metric units from '%' to 'percent' to fix dashboard issues 12 | * Fix for AIX disk & memory reporting 13 | * Fix for OSX disk & memory reporting 14 | * Fix for Linux disk reporting 15 | * Fix for IBM WebSphere JDK for IBM JSSE when the WebSphere Socket factory "classNotFound" exception. [Click here for details on how to apply fix](#ibmjsse) 16 | 17 | ### Previous updates 18 | 19 | #### V3.5 20 | 21 | * New Summary Metrics (CPU, Memory & Fullest Disk) to closer match New Relic Servers and to facilitate alerting 22 | 23 | ### NOTE: If all of your Summary Metrics disappeared like this (below), UPGRADE TO THE LATEST VERSION! 24 | ![Pic of Busted Summary](/img/you_need_to_upgrade.png?raw=true "Summary Prior To Upgrade") 25 | 26 | #### V3.4 27 | 28 | * Automatic locating of Java & plugin dir 29 | * Automatic copying of the plugin.json template for your OS 30 | 31 | #### V3.3 32 | * [Global configurations in plugin.json](#globalconf) 33 | * Bug fixes for Linux & OSX commands 34 | * More accurate data collection from commands that have produce a "per interval" measurement (i.e. iostat, vmstat) 35 | 36 | #### V3.0 37 | 38 | * OS X/macOS support! 39 | * Tested on Yosemite (10.10) and Sierra (10.12), please let me know if it works for you on other OS X versions. 40 | * Support for setting your own hostname 41 | * Support for "netstat" and "ps" commands on all platforms 42 | * MUCH improved parsing of commands, now using regex 43 | 44 | * Plugin has been upgraded to V2.0.1 of the New Relic Platform Java SDK, which adds a few key features: 45 | * 'newrelic.properties' file is now 'newrelic.json' 46 | * Plugin configuration is now done through 'plugin.json' 47 | * Logging configuration has been simplified and consolidated to 'newrelic.json' 48 | * HTTP/S proxies are now supported using 'newrelic.json'. [Click here for proxy config details](#proxyconfig) 49 | 50 | ---- 51 | 52 | ### Requirements 53 | 54 | - A New Relic account. Sign up for a free account [here](http://newrelic.com) 55 | - A unix server that you want to monitor 56 | - Java Runtime (JRE) environment Version 1.6 or later 57 | - Network access to New Relic (proxies are supported, see details below) 58 | 59 | ---- 60 | 61 | ### Installation & Usage Overview 62 | 63 | 1. Download the latest version of the agent: [newrelic_unix_plugin.tar.gz](https://github.com/sschwartzman/newrelic-unix-plugin/blob/master/dist/newrelic_unix_plugin.tar.gz?raw=true) 64 | 2. Gunzip & untar on Unix server that you want to monitor 65 | 3. Configure `config/newrelic.json` 66 | * [Click here for newrelic.json config details](#nrjson) 67 | 4. OPTIONAL: Copy `config/plugin.json` from the OS-specific templates in `config` and configure that file. 68 | * [Click here for plugin.json config details](#pluginjson) 69 | 5. OPTIONAL: Configure `pluginctl.sh` to have the correct paths to Java and your plugin location 70 | * Set `PLUGIN_JAVA` to the location of Java on your server (including the "java" filename) 71 | * Set `PLUGIN_PATH` to the location of the Unix Plugin 72 | 6. Run `chmod +x pluginctl.sh` to make the startup script executable (if it isn't already) 73 | 7. Run `./pluginctl.sh start` from command-line 74 | 8. Check logs (in `logs` directory by default) for errors 75 | 9. Login to New Relic UI and find your plugin instance 76 | * In the New Relic UI, select "Plugins" from the top level accordion menu 77 | * Check for the "Unix" plugin in left-hand column. Click on it, your instance should appear in the list. 78 | 79 | ---- 80 | 81 | ### Configuring the `newrelic.json` file 82 | 83 | The `newrelic.json` is a standardized file containing configuration information that applies to any plugin (e.g. license key, logging, proxy settings), so going forward you will be able to copy a single `newrelic.json` file from one plugin to another. Below is a list of the configuration fields that can be managed through this file: 84 | 85 | #### Configuring your New Relic License Key 86 | 87 | * Your New Relic license key is the only required field in the `newrelic.json` file as it is used to determine what account you are reporting to. 88 | * Your license key can be found in New Relic UI, on 'Account settings' page. 89 | 90 | ##### Example 91 | 92 | ``` 93 | { 94 | "license_key": "YOUR_LICENSE_KEY_HERE" 95 | } 96 | ``` 97 | 98 | #### Logging configuration 99 | 100 | By default, this plugins will have logging turned on; however, you can manage these settings with the following configurations: 101 | 102 | * `log_level` - The log level. Valid values: [`debug`, `info`, `warn`, `error`, `fatal`]. Defaults to `info`. 103 | * `debug` will expose the metrics being collected by each command. 104 | * `log_file_name` - The log file name. Defaults to `newrelic_plugin.log`. 105 | * `log_file_path` - The log file path. Defaults to `logs`. 106 | * `log_limit_in_kbytes` - The log file limit in kilobytes. Defaults to `25600` (25 MB). If limit is set to `0`, the log file size will not be limited. 107 | 108 | ##### Example 109 | 110 | ``` 111 | { 112 | "license_key": "YOUR_LICENSE_KEY_HERE" 113 | "log_level": "info", 114 | "log_file_path": "/var/log/newrelic", 115 | "log_limit_in_kbytes": "4096" 116 | } 117 | ``` 118 | 119 | #### Proxy configuration 120 | 121 | If you are running your plugin from a machine that runs outbound traffic through a proxy, you can use the following optional configurations in your `newrelic.json` file: 122 | 123 | * `proxy_host` - The proxy host (e.g. `webcache.example.com`) 124 | * `proxy_port` - The proxy port (e.g. `8080`). Defaults to `80` if a `proxy_host` is set 125 | * `proxy_username` - The proxy username 126 | * `proxy_password` - The proxy password 127 | 128 | ##### Examples 129 | 130 | ``` 131 | { 132 | "license_key": "YOUR_LICENSE_KEY_HERE", 133 | "proxy_host": "proxy.mycompany.com", 134 | "proxy_port": 9000 135 | } 136 | ``` 137 | 138 | ``` 139 | { 140 | "license_key": "YOUR_LICENSE_KEY_HERE", 141 | "proxy_host": "proxy.mycompany.com", 142 | "proxy_port": "9000", 143 | "proxy_username": "my_user", 144 | "proxy_password": "my_password" 145 | } 146 | ``` 147 | 148 | ---- 149 | 150 | ### Configuring the `plugin.json` file 151 | 152 | The `plugin.json` file contains the list of OS level commands that you want to execute as part of the plugin, and global settings to apply across all commands. All current possibilities for each OS are found in the `config/plugin.json.[OS]` template files. 153 | To set up the agent for your OS, copy one of these templates to `plugin.json`. If you don't do this, the plugin will do it for you the first time it is run. 154 | 155 | Each command will get its own object in the `agents` array, as seen in the Example below. 156 | `command` is the only required configuration for each object. Commands in lowercase are ones literally defined in the plugin (i.e. `iostat`), whereas commands in Caps are specialized variations on those commands (i.e. `IostatCPU`). 157 | 158 | #### Global Configurations 159 | 160 | Each plugin.json file now has a `global` object, which contains the optional configurations to be applied across all of the commands. 161 | 162 | * Configurations in the `agents` array override what's in the `global` object. 163 | - I.e. If you want to turn on debug for one statement, you can set the `debug` object to false in the `global` object, and set it to true in that command's `agent` object. 164 | * If you choose to use the old versions of plugin.json (without a `global` option), those will work fine. 165 | 166 | #### Optional Configurations for `plugin.json` 167 | 168 | For each command, the following optional configurations are available: 169 | 170 | * `OS` - The OS you are monitoring. 171 | - If left out, it will use the "auto" setting, in which the plugin will detect your OS type. 172 | - Normally the "auto" setting works fine. If not, you can define it as any of: [aix, linux, sunos, osx]. 173 | * `debug` - This is an extra debug setting to use when a specific command isn't reporting properly. 174 | - Enabling it will prevent metrics from being sent to New Relic. 175 | - Seeing metrics in logs also requires setting `"log_level": "debug"` in `newrelic.json`. 176 | * `hostname` - To override the hostname that appears in the UI for this instance, set this option to any string that you want. 177 | - If you leave this option out, the plugin will obtain your hostname from the JVM (java.net.InetAddress.getLocalHost().getHostName()) 178 | 179 | #### Examples 180 | 181 | With the optional configurations left as the defaults, this is what your plugin.json might look like: 182 | ``` 183 | { 184 | "global": { 185 | "OS": "auto", 186 | "debug": false, 187 | "hostname": "auto" 188 | }, 189 | "agents": [ 190 | { 191 | "command": "df" 192 | }, 193 | { 194 | "command": "iostat" 195 | }, 196 | { 197 | "command": "top" 198 | }, 199 | { 200 | "command": "vmstat" 201 | }, 202 | { 203 | "command": "VmstatTotals" 204 | } 205 | ] 206 | } 207 | ``` 208 | Here is an example with optional configurations set in the `agent` object that override the `global` settings: 209 | ``` 210 | { 211 | "global": { 212 | "OS": "auto", 213 | "debug": false, 214 | "hostname": "auto" 215 | }, 216 | "agents": [ 217 | { 218 | "command": "df", 219 | "debug": true 220 | }, 221 | { 222 | "command": "iostat", 223 | "hostname": "not auto" 224 | }, 225 | { 226 | "command": "top", 227 | "OS": "linux", 228 | "hostname": "also not auto" 229 | }, 230 | { 231 | "command": "vmstat" 232 | }, 233 | { 234 | "command": "VmstatTotals" 235 | } 236 | ] 237 | } 238 | ``` 239 | 240 | ### Fix for using the IBM (WebSphere) JDK 241 | 242 | If you are using the JDK that is packaged with WebSphere see an exception in the logs like below, it is due to WebSphere attempting to use the WebSphere SSL Factory instead of the IBM JSSE packages. 243 | ``` 244 | ERROR com.newrelic.metrics.publish.binding.Request - An error occurred communicating with the New Relic service 245 | java.net.SocketException: java.lang.ClassNotFoundException: Cannot find the specified class com.ibm.websphere.ssl.protocol.SSLSocketFactory 246 | ``` 247 | 248 | If so, uncomment the following line in `pluginctl.sh` and restart the agent. 249 | ``` 250 | # USE_IBM_JSSE=true 251 | ``` 252 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | Cleaning project. 36 | 37 | Done. 38 | 39 | 40 | 41 | 42 | 43 | Creating directory: ${build.dir} 44 | 45 | 46 | 47 | 48 | Updating version number. 49 | 53 | Building project. 54 | 55 | 56 | 57 | 58 | Done. 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /config/newrelic.json: -------------------------------------------------------------------------------- 1 | { 2 | "license_key": "YOUR_LICENSE_KEY_HERE", 3 | "log_level": "info", 4 | "log_file_name": "newrelic_plugin.log", 5 | "log_file_path": "logs", 6 | "log_limit_in_kbytes": 10000 7 | } 8 | -------------------------------------------------------------------------------- /config/plugin.json.aix: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "OS": "auto", 4 | "hostname": "auto", 5 | "debug": false 6 | }, 7 | "agents": [ 8 | { 9 | "command": "df" 10 | }, 11 | { 12 | "command": "entstat" 13 | }, 14 | { 15 | "command": "iostat" 16 | }, 17 | { 18 | "command": "lparstat" 19 | }, 20 | { 21 | "command": "ps" 22 | }, 23 | { 24 | "command": "svmon" 25 | }, 26 | { 27 | "command": "uptime" 28 | }, 29 | { 30 | "command": "vmstat" 31 | }, 32 | { 33 | "command": "VmstatThreads" 34 | }, 35 | { 36 | "command": "VmstatTotals" 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /config/plugin.json.linux: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "OS": "auto", 4 | "hostname": "auto", 5 | "debug": false 6 | }, 7 | "agents": [ 8 | { 9 | "command": "df" 10 | }, 11 | { 12 | "command": "iostat" 13 | }, 14 | { 15 | "command": "NetworkIO" 16 | }, 17 | { 18 | "command": "ps" 19 | }, 20 | { 21 | "command": "top" 22 | }, 23 | { 24 | "command": "vmstat" 25 | }, 26 | { 27 | "command": "VmstatTotals" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /config/plugin.json.osx: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "OS": "auto", 4 | "hostname": "auto", 5 | "debug": false 6 | }, 7 | "agents": [ 8 | { 9 | "command": "df" 10 | }, 11 | { 12 | "command": "iostat" 13 | }, 14 | { 15 | "command": "netstat" 16 | }, 17 | { 18 | "command": "ps" 19 | }, 20 | { 21 | "command": "top" 22 | }, 23 | { 24 | "command": "vm_stat" 25 | }, 26 | { 27 | "command": "VmstatTotals" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /config/plugin.json.solaris_10: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "OS": "auto", 4 | "hostname": "auto", 5 | "debug": false 6 | }, 7 | "agents": [ 8 | { 9 | "command": "df" 10 | }, 11 | { 12 | "command": "iostat" 13 | }, 14 | { 15 | "command": "IostatCPU" 16 | }, 17 | { 18 | "command": "KstatNetwork" 19 | }, 20 | { 21 | "command": "KstatPages" 22 | }, 23 | { 24 | "command": "prstat" 25 | }, 26 | { 27 | "command": "ps" 28 | }, 29 | { 30 | "command": "swap" 31 | }, 32 | { 33 | "command": "VmstatPagesFaults" 34 | }, 35 | { 36 | "command": "VmstatThreadsMemory" 37 | }, 38 | { 39 | "command": "VmstatTotals" 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /config/plugin.json.solaris_11: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "OS": "auto", 4 | "hostname": "auto", 5 | "debug": false 6 | }, 7 | "agents": [ 8 | { 9 | "command": "df" 10 | }, 11 | { 12 | "command": "iostat" 13 | }, 14 | { 15 | "command": "KstatNetwork" 16 | }, 17 | { 18 | "command": "KstatPages" 19 | }, 20 | { 21 | "command": "ps" 22 | }, 23 | { 24 | "command": "swap" 25 | }, 26 | { 27 | "command": "top" 28 | }, 29 | { 30 | "command": "VmstatPagesFaults" 31 | }, 32 | { 33 | "command": "VmstatThreadsMemory" 34 | }, 35 | { 36 | "command": "VmstatTotals" 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /dist/newrelic_unix_plugin.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sschwartzman/newrelic-unix-plugin/5375edc4c7c4cb36624d2daa04e580c04d458258/dist/newrelic_unix_plugin.tar.gz -------------------------------------------------------------------------------- /etc/ibm_jsse.java.security: -------------------------------------------------------------------------------- 1 | ssl.SocketFactory.provider=com.ibm.jsse2.SSLSocketFactoryImpl 2 | ssl.ServerSocketFactory.provider=com.ibm.jsse2.SSLServerSocketFactoryImpl 3 | -------------------------------------------------------------------------------- /hashbang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sschwartzman/newrelic-unix-plugin/5375edc4c7c4cb36624d2daa04e580c04d458258/hashbang.png -------------------------------------------------------------------------------- /img/you_need_to_upgrade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sschwartzman/newrelic-unix-plugin/5375edc4c7c4cb36624d2daa04e580c04d458258/img/you_need_to_upgrade.png -------------------------------------------------------------------------------- /lib/json-simple-1.1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sschwartzman/newrelic-unix-plugin/5375edc4c7c4cb36624d2daa04e580c04d458258/lib/json-simple-1.1.1.jar -------------------------------------------------------------------------------- /lib/metrics_publish-2.0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sschwartzman/newrelic-unix-plugin/5375edc4c7c4cb36624d2daa04e580c04d458258/lib/metrics_publish-2.0.1.jar -------------------------------------------------------------------------------- /plugin_jar.jardesc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /pluginctl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # chkconfig: 2345 20 80 3 | # description: Unix system plugin for New Relic 4 | # processname: NR Unix Agent 5 | 6 | ### Set these as appropriate ### 7 | 8 | # Change to false if you want to append to existing logs. 9 | DELETE_LOGS_ON_STARTUP=true 10 | 11 | # Uncomment if you are using a JDK packaged with WebSphere 12 | # USE_IBM_JSSE=true 13 | 14 | # Uncomment to manually define Plugin path if this script can't find it 15 | # PLUGIN_PATH=/opt/newrelic/newrelic_unix_plugin 16 | 17 | # Uncomment to manually define Java path & filename if this script can't find it 18 | # AIX: 19 | # PLUGIN_JAVA=/usr/java6/bin/java 20 | # LINUX, OSX & SOLARIS: 21 | # PLUGIN_JAVA=/usr/bin/java 22 | 23 | ### Do not change these unless instructed! ### 24 | 25 | PLUGIN_NAME="New Relic Unix Plugin" 26 | 27 | # Behavior when "start" command is issued and plugin is running 28 | # False (default): Plugin will not be restarted. 29 | # True: Plugin will be restarted. 30 | PLUGIN_RESTART_ON_START=false 31 | 32 | # Attempt to set plugin path if not manually defined above 33 | if [ -z "$PLUGIN_PATH" ]; then 34 | RELATIVE_PATH=`dirname "$0"` 35 | PLUGIN_PATH=`eval "cd \"$RELATIVE_PATH\" && pwd"` 36 | fi 37 | echo "Plugin location: $PLUGIN_PATH" 38 | 39 | # Comment-out if using -jar 40 | PLUGIN_JAVA_CLASS=com.chocolatefactory.newrelic.plugins.unix.Main 41 | # Set to the jar if using -jar 42 | PLUGIN_JAVA_CLASSPATH="$PLUGIN_PATH/bin/newrelic_unix_plugin.jar:$PLUGIN_PATH/lib/metrics_publish-2.0.1.jar:$PLUGIN_PATH/lib/json-simple-1.1.1.jar" 43 | PLUGIN_JAVA_OPTS="-Xms16m -Xmx128m" 44 | 45 | # Attempt to set Java path & filename if not manually defined above 46 | if [ -z "$PLUGIN_JAVA" ]; then 47 | if [ -n "$JAVA_HOME" ]; then 48 | PLUGIN_JAVA=$JAVA_HOME/bin/java 49 | else 50 | PLUGIN_JAVA=`which java` 51 | fi 52 | # If attempt to set Java path & filename failed, throw error 53 | if [ -z "$PLUGIN_JAVA" ]; then 54 | echo "Could not find Java and is not manually defined." 55 | echo "Please edit pluginctl.sh and set PLUGIN_JAVA to a valid Java binary." 56 | exit 1 57 | fi 58 | fi 59 | 60 | PLUGIN_HOST_OS=`uname` 61 | PLUGIN_JAVA_VERSION_FULL=`$PLUGIN_JAVA -Xmx32m -version 2>&1` 62 | 63 | if [ "$PLUGIN_HOST_OS" = "SunOS" ]; then 64 | AWK_COMMAND="nawk" 65 | else 66 | AWK_COMMAND="awk" 67 | fi 68 | 69 | PLUGIN_JAVA_VERSION=`echo $PLUGIN_JAVA_VERSION_FULL | $AWK_COMMAND -F '"' '/version/ {print $2}'` 70 | PLUGIN_JAVA_MAJOR_VERSION=`echo $PLUGIN_JAVA_VERSION | $AWK_COMMAND '{split($0, array, ".")} END{print array[2]}'` 71 | 72 | echo "Java location: $PLUGIN_JAVA" 73 | echo "Java version: $PLUGIN_JAVA_VERSION" 74 | 75 | if [ $PLUGIN_JAVA_MAJOR_VERSION -lt 6 ]; then 76 | echo "ERROR: $PLUGIN_NAME will not work with Java versions older than 1.6." 77 | echo "Please edit pluginctl.sh and set PLUGIN_JAVA to a Java distro (Sun/Oracle, IBM, OpenJDK) v1.6 or above." 78 | exit 1 79 | fi 80 | 81 | if echo $PLUGIN_JAVA_VERSION_FULL | grep -c -q 'gcj'; then 82 | echo "ERROR: $PLUGIN_NAME will not work with gcj." 83 | echo "Please edit pluginctl.sh and set PLUGIN_JAVA to another Java distro (Sun/Oracle, IBM, OpenJDK)." 84 | echo "Output of \"java -version\":\n $PLUGIN_JAVA_VERSION_FULL" 85 | exit 1 86 | fi 87 | 88 | PLUGIN_ERR_FILE=$PLUGIN_PATH/logs/newrelic_plugin.err 89 | PLUGIN_LOG_FILE=$PLUGIN_PATH/logs/newrelic_plugin.log 90 | PLUGIN_PID_FILE=$PLUGIN_PATH/logs/newrelic_plugin.pid 91 | 92 | # Added for IBM JSSE support 93 | if [ -n "$USE_IBM_JSSE" ] && [ "$USE_IBM_JSSE" = "true" ]; then 94 | PLUGIN_SEC_FILE=$PLUGIN_PATH/etc/ibm_jsse.java.security 95 | echo "Using IBM JSSE, classes defined in $PLUGIN_SEC_FILE" 96 | PLUGIN_JAVA_OPTS="$PLUGIN_JAVA_OPTS -Djava.security.properties=$PLUGIN_SEC_FILE" 97 | fi 98 | 99 | if [ -n "$PLUGIN_JAVA_CLASS" ]; then 100 | PLUGIN_JAVA_FULL_COMMAND="$PLUGIN_JAVA $PLUGIN_JAVA_OPTS -cp $PLUGIN_JAVA_CLASSPATH $PLUGIN_JAVA_CLASS" 101 | else 102 | PLUGIN_JAVA_FULL_COMMAND="$PLUGIN_JAVA $PLUGIN_JAVA_OPTS -jar $PLUGIN_JAVA_CLASSPATH" 103 | fi 104 | 105 | check_plugin_status() { 106 | echo "Checking $PLUGIN_NAME" 107 | if [ -f $PLUGIN_PID_FILE ]; then 108 | PID=`cat $PLUGIN_PID_FILE` 109 | if [ -z "`ps -ef | grep ${PID} | grep -v grep`" ]; then 110 | echo "Process dead but $PLUGIN_PID_FILE exists" 111 | echo "Deleting $PLUGIN_PID_FILE" 112 | rm -f $PLUGIN_PID_FILE 113 | procstatus=0 114 | else 115 | echo "$PLUGIN_NAME is running with PID $PID" 116 | procstatus=1 117 | fi 118 | else 119 | echo "$PLUGIN_NAME is not running" 120 | procstatus=0 121 | fi 122 | return "$procstatus" 123 | } 124 | 125 | stop_plugin() { 126 | check_plugin_status 127 | procstatus=$? 128 | if [ "$procstatus" -eq 1 ] && [ -f $PLUGIN_PID_FILE ]; then 129 | echo "Stopping $PLUGIN_NAME" | tee -a $PLUGIN_ERR_FILE 130 | PID=`cat $PLUGIN_PID_FILE` 131 | kill -9 $PID 132 | echo "$PLUGIN_NAME running with PID $PID stopped" | tee -a $PLUGIN_ERR_FILE 133 | rm -f $PLUGIN_PID_FILE 134 | else 135 | echo "$PLUGIN_NAME is not running or $PLUGIN_PID_FILE not found" 136 | fi 137 | } 138 | 139 | start_plugin() { 140 | mkdir -p $PLUGIN_PATH/logs 141 | check_plugin_status 142 | procstatus=$? 143 | if [ "$procstatus" -eq 1 ]; then 144 | if [ "$PLUGIN_RESTART_ON_START" = "false" ]; then 145 | echo "Plugin is already running, restart will not occur" 146 | exit 2 147 | elif [ "$PLUGIN_RESTART_ON_START" = "true" ]; then 148 | echo "Restarting $PLUGIN_NAME" 149 | stop_plugin 150 | else 151 | echo "Plugin is already running, restart will not occur" 152 | exit 2 153 | fi 154 | fi 155 | 156 | if [ "$DELETE_LOGS_ON_STARTUP" = true ] ; then 157 | echo "Deleting logs" 158 | rm -f $PLUGIN_ERR_FILE 159 | rm -f $PLUGIN_LOG_FILE 160 | fi 161 | 162 | echo "####################" >> $PLUGIN_ERR_FILE 163 | echo "Starting $PLUGIN_NAME" | tee -a $PLUGIN_ERR_FILE 164 | echo "Host OS: $PLUGIN_HOST_OS" >> $PLUGIN_ERR_FILE 165 | echo "Java location: $PLUGIN_JAVA" >> $PLUGIN_ERR_FILE 166 | echo "Java version: $PLUGIN_JAVA_VERSION_FULL" >> $PLUGIN_ERR_FILE 167 | echo "Plugin location: $PLUGIN_PATH" >> $PLUGIN_ERR_FILE 168 | echo "Plugin startup command: $PLUGIN_JAVA_FULL_COMMAND" >> $PLUGIN_ERR_FILE 169 | 170 | nohup $PLUGIN_JAVA_FULL_COMMAND >/dev/null 2>>$PLUGIN_ERR_FILE & 171 | PID=`echo $!` 172 | if [ -z $PID ]; then 173 | echo "$PLUGIN_NAME failed to start" | tee -a $PLUGIN_ERR_FILE 174 | echo "####################" >> $PLUGIN_ERR_FILE 175 | exit 1 176 | else 177 | echo $PID > $PLUGIN_PID_FILE 178 | echo "$PLUGIN_NAME started with PID $PID" | tee -a $PLUGIN_ERR_FILE 179 | echo "####################" >> $PLUGIN_ERR_FILE 180 | exit 0 181 | fi 182 | } 183 | 184 | echo "" 185 | case "$1" in 186 | status) 187 | check_plugin_status 188 | ;; 189 | start) 190 | start_plugin 191 | ;; 192 | restart) 193 | echo "Restarting $PLUGIN_NAME" 194 | stop_plugin 195 | start_plugin 196 | ;; 197 | stop) 198 | stop_plugin 199 | ;; 200 | stopremlogs) 201 | stop_plugin 202 | echo "Clearing plugin logs" 203 | rm -f $PLUGIN_PATH/logs/* 204 | ;; 205 | *) 206 | echo "Usage: $0 [status|start|stop|stopremlogs|restart]" 207 | exit 1 208 | esac 209 | -------------------------------------------------------------------------------- /src/com/chocolatefactory/newrelic/plugins/unix/AIXMetrics.java: -------------------------------------------------------------------------------- 1 | package com.chocolatefactory.newrelic.plugins.unix; 2 | 3 | import java.util.HashMap; 4 | import java.util.regex.Pattern; 5 | 6 | import com.chocolatefactory.newrelic.plugins.utils.MetricDetail; 7 | import com.chocolatefactory.newrelic.plugins.utils.MetricDetail.metricTypes; 8 | import com.chocolatefactory.newrelic.plugins.utils.CommandMetricUtils; 9 | 10 | public class AIXMetrics extends UnixMetrics { 11 | 12 | public static final String kDefaultAgentName = "AIX"; 13 | 14 | public AIXMetrics() { 15 | 16 | super(); 17 | 18 | /* 19 | * Parser & declaration for 'df' command 20 | */ 21 | HashMap dfMapping = new HashMap(); 22 | dfMapping.put(Pattern.compile("\\s*(\\S+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)%\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)%.*"), 23 | new String[]{kColumnMetricDiskName, "1K-blocks", "Used", "Available", "Use%", "Iused", "Ifree", "Iuse%"}); 24 | allCommands.put("df", new UnixCommand(new String[]{"df","-v","-k"}, commandTypes.REGEXDIM, defaultignores, 0, dfMapping)); 25 | allMetrics.put(CommandMetricUtils.mungeString("df", "1K-blocks"), new MetricDetail("Disk", "Total", "kb", metricTypes.NORMAL, 1)); 26 | allMetrics.put(CommandMetricUtils.mungeString("df", "Used"), new MetricDetail("Disk", "Used", "kb", metricTypes.NORMAL, 1)); 27 | allMetrics.put(CommandMetricUtils.mungeString("df", "Available"), new MetricDetail("Disk", "Free", "kb", metricTypes.NORMAL, 1)); 28 | allMetrics.put(CommandMetricUtils.mungeString("df", "Use%"), new MetricDetail("Disk", "Used", "percent", metricTypes.NORMAL, 1)); 29 | allMetrics.put(CommandMetricUtils.mungeString("df", "Iused"), new MetricDetail("Disk", "Inodes Used", "inodes", metricTypes.NORMAL, 1)); 30 | allMetrics.put(CommandMetricUtils.mungeString("df", "Ifree"), new MetricDetail("Disk", "Inodes Free", "inodes", metricTypes.NORMAL, 1)); 31 | allMetrics.put(CommandMetricUtils.mungeString("df", "Iuse%"), new MetricDetail("Disk", "Inodes Used", "percent", metricTypes.NORMAL, 1)); 32 | 33 | /* 34 | * Parser & declaration for 'entstat' command 35 | */ 36 | HashMap entstatMapping = new HashMap(); 37 | entstatMapping.put(Pattern.compile(".*Packets:\\s+([0-9\\.]+)\\s+Packets:\\s+([0-9\\.]+)"), 38 | new String[]{"Transmit/Packets", "Receive/Packets"}); 39 | entstatMapping.put(Pattern.compile(".*Bytes:\\s+([0-9\\.]+)\\s+Bytes:\\s+([0-9\\.]+)"), 40 | new String[]{"Transmit/Bytes", "Receive/Bytes"}); 41 | entstatMapping.put(Pattern.compile(".*Interrupts:\\s+([0-9\\.]+)\\s+Interrupts:\\s+([0-9\\.]+)"), 42 | new String[]{"Transmit/Interrupts", "Receive/Interrupts"}); 43 | entstatMapping.put(Pattern.compile(".*Transmit\\s+Errors:\\s+([0-9\\.]+)\\s+Receive\\s+Errors:\\s+([0-9\\.]+)"), 44 | new String[]{"Transmit/Errors", "Receive/Errors"}); 45 | entstatMapping.put(Pattern.compile(".*Packets\\s+Dropped:\\s+([0-9\\.]+)\\s+Packets\\s+Dropped:\\s+([0-9\\.]+)"), 46 | new String[]{"Transmit/Dropped Packets", "Receive/Dropped Packets"}); 47 | entstatMapping.put(Pattern.compile(".*Max\\s+Packets\\s+on\\s+S/W\\s+Transmit\\s+Queue:\\s+([0-9\\.]+)"), 48 | new String[]{"Transmit/Max Packets on SW Transmit Queue"}); 49 | entstatMapping.put(Pattern.compile(".*S/W\\s+Transmit\\s+Queue\\s+Overflow:\\s+([0-9\\.]+)"), 50 | new String[]{"Transmit/Transmit Queue Overflow"}); 51 | entstatMapping.put(Pattern.compile(".*Current\\s+S/W\\+H/W\\s+Transmit\\s+Queue\\s+Length:\\s+([0-9\\.]+)"), 52 | new String[]{"Transmit/Current SW+HW Transmit Queue Length"}); 53 | entstatMapping.put(Pattern.compile(".*Broadcast\\s+Packets:\\s+([0-9\\.]+)\\s+Broadcast\\s+Packets:\\s+([0-9\\.]+)"), 54 | new String[]{"Transmit/Broadcast Packets", "Receive/Broadcast Packets"}); 55 | entstatMapping.put(Pattern.compile(".*Multicast\\s+Packets:\\s+([0-9\\.]+)\\s+Multicast\\s+Packets:\\s+([0-9\\.]+)"), 56 | new String[]{"Transmit/Multicast Packets", "Receive/Multicast Packets"}); 57 | entstatMapping.put(Pattern.compile(".*No Carrier\\s+Sense:\\s+([0-9\\.]+)\\s+CRC\\s+Errors:\\s+([0-9\\.]+)"), 58 | new String[]{"Transmit/No Carrier Sense", "Receive/CRC Errors"}); 59 | entstatMapping.put(Pattern.compile(".*DMA\\s+Underrun:\\s+([0-9\\.]+)\\s+DMA\\s+Overrun:\\s+([0-9\\.]+)"), 60 | new String[]{"Transmit/DMA Underrun", "Receive/DMA Overrun"}); 61 | entstatMapping.put(Pattern.compile(".*Lost CTS\\s+Errors:\\s+([0-9\\.]+)\\s+Alignment\\s+Errors:\\s+([0-9\\.]+)"), 62 | new String[]{"Transmit/Lost CTS Errors", "Receive/Alignment Errors"}); 63 | entstatMapping.put(Pattern.compile(".*Max Collision\\s+Errors:\\s+([0-9\\.]+)\\s+No Resource\\s+Errors:\\s+([0-9\\.]+)"), 64 | new String[]{"Transmit/Max Collision Errors", "Receive/No Resource Errors"}); 65 | entstatMapping.put(Pattern.compile(".*Late Collision\\s+Errors:\\s+([0-9\\.]+)\\s+Receive Collision\\s+Errors:\\s+([0-9\\.]+)"), 66 | new String[]{"Transmit/Late Collision Errors", "Receive/Receive Collision Errors"}); 67 | entstatMapping.put(Pattern.compile(".*Deferred:\\s+([0-9\\.]+)\\s+Packet Too Short\\s+Errors:\\s+([0-9\\.]+)"), 68 | new String[]{"Transmit/Deferred", "Receive/Packet Too Short Errors"}); 69 | entstatMapping.put(Pattern.compile(".*SQE\\s+Test:\\s+([0-9\\.]+)\\s+Packet Too Long\\s+Errors:\\s+([0-9\\.]+)"), 70 | new String[]{"Transmit/SQE Test", "Receive/Packet Too Long Errors"}); 71 | entstatMapping.put(Pattern.compile(".*Timeout\\s+Errors:\\s+([0-9\\.]+)\\s+Packets Discarded by\\s+Adapter:\\s+([0-9\\.]+)"), 72 | new String[]{"Transmit/Timeout Errors", "Receive/Packets Discarded by Adapter"}); 73 | entstatMapping.put(Pattern.compile(".*Single Collision\\s+Count:\\s+([0-9\\.]+)\\s+Receiver Start\\s+Count:\\s+([0-9\\.]+)"), 74 | new String[]{"Transmit/Single Collision Count", "Receive/Receiver Start Count"}); 75 | entstatMapping.put(Pattern.compile(".*Multiple Collision\\s+Count:\\s+([0-9\\.]+)"), 76 | new String[]{"Transmit/Multiple Collision Count"}); 77 | entstatMapping.put(Pattern.compile(".*Current HW Transmit Queue\\s+Length:\\s+([0-9\\.]+)"), 78 | new String[]{"Transmit/Current HW Transmit Queue Length"}); 79 | allCommands.put("entstat", new UnixCommand(new String[]{"entstat", UnixMetrics.kMemberPlaceholder}, commandTypes.REGEXLISTDIM, defaultignores, 0, entstatMapping)); 80 | 81 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Packets"), new MetricDetail("Network", "Transmit/Packets", "packets", metricTypes.DELTA, 1)); 82 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Bytes"), new MetricDetail("Network", "Transmit/Bytes", "bytes", metricTypes.DELTA, 1)); 83 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Interrupts"), new MetricDetail("Network", "Transmit/Interrupts", "interrupts", metricTypes.DELTA, 1)); 84 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Errors"), new MetricDetail("Network", "Transmit/Errors", "errors", metricTypes.DELTA, 1)); 85 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Packets Dropped"), new MetricDetail("Network", "Transmit/Dropped", "packets", metricTypes.DELTA, 1)); 86 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Max Packets on SW Transmit Queue"), new MetricDetail("Network", "Transmit/Max Packets on SW Transmit Queue", "packets", metricTypes.DELTA, 1)); 87 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/SW Transmit Queue Overflow"), new MetricDetail("Network", "Transmit/SW Transmit Queue Overflow", "packets", metricTypes.DELTA, 1)); 88 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Current SW+HW Transmit Queue Length"), new MetricDetail("Network", "Transmit/Current SW+HW Transmit Queue Length", "packets", metricTypes.DELTA, 1)); 89 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Broadcast Packets"), new MetricDetail("Network", "Transmit/Broadcast Packets", "packets", metricTypes.DELTA, 1)); 90 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Multicast Packets"), new MetricDetail("Network", "Transmit/Multicast Packets", "packets", metricTypes.DELTA, 1)); 91 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/No Carrier Sense"), new MetricDetail("Network", "Transmit/No Carrier Sense", "transmissions", metricTypes.DELTA, 1)); 92 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/DMA Underrun"), new MetricDetail("Network", "Transmit/DMA Underrun", "transmissions", metricTypes.DELTA, 1)); 93 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Lost CTS Errors"), new MetricDetail("Network", "Transmit/Lost CTS Errors", "transmissions", metricTypes.DELTA, 1)); 94 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Max Collision Errors"), new MetricDetail("Network", "Transmit/Max Collision Errors", "transmissions", metricTypes.DELTA, 1)); 95 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Late Collision Errors"), new MetricDetail("Network", "Transmit/Late Collision Errors", "transmissions", metricTypes.DELTA, 1)); 96 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Deferred"), new MetricDetail("Network", "Transmit/Deferred", "packets", metricTypes.DELTA, 1)); 97 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/SQE Test"), new MetricDetail("Network", "Transmit/SQE Test", "tests", metricTypes.DELTA, 1)); 98 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Timeout Errors"), new MetricDetail("Network", "Transmit/Timeout Errors", "transmissions", metricTypes.DELTA, 1)); 99 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Single Collision Count"), new MetricDetail("Network", "Transmit/Single Collision Count", "packets", metricTypes.DELTA, 1)); 100 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Multiple Collision Count"), new MetricDetail("Network", "Transmit/Multiple Collision Count", "packets", metricTypes.DELTA, 1)); 101 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Transmit/Current HW Transmit Queue Length"), new MetricDetail("Network", "Transmit/Current HW Transmit Queue Length", "packets", metricTypes.DELTA, 1)); 102 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Packets"), new MetricDetail("Network", "Receive/Packets", "packets", metricTypes.DELTA, 1)); 103 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Bytes"), new MetricDetail("Network", "Receive/Bytes", "bytes", metricTypes.DELTA, 1)); 104 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Interrupts"), new MetricDetail("Network", "Receive/Interrupts", "interrupts", metricTypes.DELTA, 1)); 105 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Errors"), new MetricDetail("Network", "Receive/Errors", "errors", metricTypes.DELTA, 1)); 106 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Packets Dropped"), new MetricDetail("Network", "Receive/Dropped", "packets", metricTypes.DELTA, 1)); 107 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Bad Packets"), new MetricDetail("Network", "Receive/Bad Packets", "packets", metricTypes.DELTA, 1)); 108 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Broadcast Packets"), new MetricDetail("Network", "Receive/Broadcast Packets", "packets", metricTypes.DELTA, 1)); 109 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Multicast Packets"), new MetricDetail("Network", "Receive/Multicast Packets", "packets", metricTypes.DELTA, 1)); 110 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/CRC Errors"), new MetricDetail("Network", "Receive/CRC Errors", "errors", metricTypes.DELTA, 1)); 111 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/DMA Overrun"), new MetricDetail("Network", "Receive/DMA Overrun", "packets", metricTypes.DELTA, 1)); 112 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Alignment Errors"), new MetricDetail("Network", "Receive/Alignment Errors", "errors", metricTypes.DELTA, 1)); 113 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/No Resource Errors"), new MetricDetail("Network", "Receive/No Resource Errors", "errors", metricTypes.DELTA, 1)); 114 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Receive Collision Errors"), new MetricDetail("Network", "Receive/Receive Collision Errors", "errors", metricTypes.DELTA, 1)); 115 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Packet Too Short Errors"), new MetricDetail("Network", "Receive/Packet Too Short Errors", "errors", metricTypes.DELTA, 1)); 116 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Packet Too Long Errors"), new MetricDetail("Network", "Receive/Packet Too Long Errors", "errors", metricTypes.DELTA, 1)); 117 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Packets Discarded by Adapter"), new MetricDetail("Network", "Receive/Packets Discarded by Adapter", "packets", metricTypes.DELTA, 1)); 118 | allMetrics.put(CommandMetricUtils.mungeString("entstat", "Receive/Receiver Start Count"), new MetricDetail("Network", "Receive/Receiver Start Count", "count", metricTypes.DELTA, 1)); 119 | 120 | /* 121 | * Parser & declaration for 'iostat' command 122 | */ 123 | HashMap iostatMapping = new HashMap(); 124 | iostatMapping.put(Pattern.compile("\\s*(\\w+\\d*)\\s+([0-9\\.]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+)"), 125 | new String[]{kColumnMetricPrefix, "tm_act", "Kbps", "tps", "Kb_read", "Kb_wrtn"}); 126 | allCommands.put("iostat", new UnixCommand(new String[]{"iostat", "-d"}, commandTypes.REGEXDIM, defaultignores, 0, iostatMapping)); 127 | 128 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "kbps"), new MetricDetail("DiskIO", "Average Data Transferred per Second", "kb", metricTypes.NORMAL, 1)); 129 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "tps"), new MetricDetail("DiskIO", "Average Transfers per Second", "transfers", metricTypes.NORMAL, 1)); 130 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "kb_read"), new MetricDetail("DiskIO", "Data Read per Interval", "kb", metricTypes.DELTA, 1)); 131 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "kb_wrtn"), new MetricDetail("DiskIO", "Data Written per Interval", "kb", metricTypes.DELTA, 1)); 132 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "tm_act"), new MetricDetail("DiskIO", "Average Percentage of Time Busy", "percent", metricTypes.NORMAL, 1)); 133 | 134 | /* 135 | * Parser & declaration for 'lparstat' command 136 | */ 137 | HashMap lparstatMapping = new HashMap(); 138 | lparstatMapping.put(Pattern.compile("\\s*([0-9\\.]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+).*"), 139 | new String[]{"user", "sys", "wait", "idle"}); 140 | allCommands.put("lparstat", new UnixCommand(new String[]{"lparstat", "1", "1"}, commandTypes.REGEXDIM, defaultignores, 0, lparstatMapping)); 141 | 142 | allMetrics.put(CommandMetricUtils.mungeString("lparstat", "user"), new MetricDetail("CPU", "User", "percent", metricTypes.NORMAL, 1)); 143 | allMetrics.put(CommandMetricUtils.mungeString("lparstat", "sys"), new MetricDetail("CPU", "System", "percent", metricTypes.NORMAL, 1)); 144 | allMetrics.put(CommandMetricUtils.mungeString("lparstat", "wait"), new MetricDetail("CPU", "IOWait", "percent", metricTypes.NORMAL, 1)); 145 | allMetrics.put(CommandMetricUtils.mungeString("lparstat", "idle"), new MetricDetail("CPU", "Idle", "percent", metricTypes.NORMAL, 1)); 146 | 147 | /* 148 | * Parser & declaration for 'netstat' command 149 | * ** NOT USED IN FAVOR OF ENTSTAT ** 150 | */ 151 | HashMap netstatMapping = new HashMap(); 152 | netstatMapping.put(Pattern.compile("\\w+\\d*\\s+(\\d+)\\s+[\\d\\.]+\\s+[\\d\\.]+" 153 | + "\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)"), 154 | new String[]{"MTU", "Iptks", "Ierrs", "Optks", "Oerrs", "Coll"}); 155 | allCommands.put("netstat", new UnixCommand(new String[]{"netstat", "-i", "-n"}, commandTypes.REGEXDIM, defaultignores, 0, netstatMapping)); 156 | 157 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "MTU"), new MetricDetail("Network", "MTU", "packets", metricTypes.NORMAL, 1)); 158 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Ipkts"), new MetricDetail("Network", "Receive/Packets", "packets", metricTypes.DELTA, 1)); 159 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Ierrs"), new MetricDetail("Network", "Receive/Errors", "errors", metricTypes.DELTA, 1)); 160 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Opkts"), new MetricDetail("Network", "Transmit/Packets", "packets", metricTypes.DELTA, 1)); 161 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Oerrs"), new MetricDetail("Network", "Transmit/Errors", "errors", metricTypes.DELTA, 1)); 162 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Coll"), new MetricDetail("Network", "Collisions", "packets", metricTypes.DELTA, 1)); 163 | 164 | /* 165 | * Parser & declaration for 'ps' command 166 | */ 167 | HashMap psMapping = new HashMap(); 168 | psMapping.put(Pattern.compile("(\\d+)\\s+\\S+\\s+\\S+\\s+\\S+\\s+\\S+\\s+" 169 | + "(\\d+)\\s+\\d+\\s+\\d+\\s+\\d+([0-9\\.]+)\\s+([0-9\\.]+)\\s+(.*)"), 170 | new String[]{"RSS", "%CPU", "%MEM", kColumnMetricProcessName}); 171 | 172 | // psMapping.put(Pattern.compile("([^\\s]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+)\\s+(\\d+)"), 173 | // new String[]{kColumnMetricPrefixCount, "%CPU", "%MEM", "RSS"}); 174 | allCommands.put("ps", new UnixCommand(new String[]{"ps", "vewww"}, 175 | commandTypes.REGEXDIM, defaultignores, 0, psMapping)); 176 | 177 | allMetrics.put(CommandMetricUtils.mungeString("ps", kColumnMetricProcessName), new MetricDetail("Processes", "Instance Count", "processes", metricTypes.INCREMENT, 1)); 178 | allMetrics.put(CommandMetricUtils.mungeString("ps", "%CPU"), new MetricDetail("Processes", "Aggregate CPU", "percent", metricTypes.INCREMENT, 1)); 179 | allMetrics.put(CommandMetricUtils.mungeString("ps", "%MEM"), new MetricDetail("Processes", "Aggregate Memory", "percent", metricTypes.INCREMENT, 1)); 180 | allMetrics.put(CommandMetricUtils.mungeString("ps", "RSS"), new MetricDetail("Processes", "Aggregate Resident Size", "kb", metricTypes.INCREMENT, 1)); 181 | 182 | /* 183 | * Parser & declaration for 'svmon' command 184 | */ 185 | HashMap svmonMapping = new HashMap(); 186 | svmonMapping.put(Pattern.compile("\\s*(memory)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+).*"), 187 | new String[]{kColumnMetricPrefix, "size", "inuse", "free", "pin", "virtual", "available"}); 188 | svmonMapping.put(Pattern.compile("\\s*(pg\\s{1}space)\\s+(\\d+)\\s+(\\d+)"), 189 | new String[]{kColumnMetricPrefix, "size", "inuse"}); 190 | svmonMapping.put(Pattern.compile("\\s*(pin)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)"), 191 | new String[]{kColumnMetricPrefix, "pin_work", "pin_pers", "pin_clnt", "pin_other"}); 192 | svmonMapping.put(Pattern.compile("\\s*(in\\s{1}use)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)"), 193 | new String[]{kColumnMetricPrefix, "inuse_work", "inuse_pers", "inuse_clnt"}); 194 | allCommands.put("svmon", new UnixCommand(new String[]{"svmon","-Ounit=KB"}, commandTypes.REGEXDIM, defaultignores, 0, svmonMapping)); 195 | 196 | allMetrics.put(CommandMetricUtils.mungeString("svmon", "size"), new MetricDetail("MemoryDetailed", "Physical/Total", "kb", metricTypes.NORMAL, 1)); 197 | allMetrics.put(CommandMetricUtils.mungeString("svmon", "inuse"), new MetricDetail("MemoryDetailed", "Physical/Total In Use", "kb", metricTypes.NORMAL, 1)); 198 | allMetrics.put(CommandMetricUtils.mungeString("svmon", "free"), new MetricDetail("MemoryDetailed", "Physical/Free", "kb", metricTypes.NORMAL, 1)); 199 | allMetrics.put(CommandMetricUtils.mungeString("svmon", "pin"), new MetricDetail("MemoryDetailed", "Pinned/Total", "kb", metricTypes.NORMAL, 1)); 200 | allMetrics.put(CommandMetricUtils.mungeString("svmon", "virtual"), new MetricDetail("Memory", "Used", "kb", metricTypes.NORMAL, 1)); 201 | allMetrics.put(CommandMetricUtils.mungeString("svmon", "available"), new MetricDetail("Memory", "Free", "kb", metricTypes.NORMAL, 1)); 202 | allMetrics.put(CommandMetricUtils.mungeString("svmon", "pin_work"), new MetricDetail("MemoryDetailed", "Pinned/Working", "kb", metricTypes.NORMAL, 1)); 203 | allMetrics.put(CommandMetricUtils.mungeString("svmon", "pin_pers"), new MetricDetail("MemoryDetailed", "Pinned/Persistent", "kb", metricTypes.NORMAL, 1)); 204 | allMetrics.put(CommandMetricUtils.mungeString("svmon", "pin_clnt"), new MetricDetail("MemoryDetailed", "Pinned/Client", "kb", metricTypes.NORMAL, 1)); 205 | allMetrics.put(CommandMetricUtils.mungeString("svmon", "pin_other"), new MetricDetail("MemoryDetailed", "Pinned/Other", "kb", metricTypes.NORMAL, 1)); 206 | allMetrics.put(CommandMetricUtils.mungeString("svmon", "inuse_work"), new MetricDetail("MemoryDetailed", "Physical/Working", "kb", metricTypes.NORMAL, 1)); 207 | allMetrics.put(CommandMetricUtils.mungeString("svmon", "inuse_pers"), new MetricDetail("MemoryDetailed", "Physical/Persistent", "kb", metricTypes.NORMAL, 1)); 208 | allMetrics.put(CommandMetricUtils.mungeString("svmon", "inuse_clnt"), new MetricDetail("MemoryDetailed", "Physical/Client", "kb", metricTypes.NORMAL, 1)); 209 | 210 | /* 211 | * Parser & declaration for 'uptime' command 212 | */ 213 | HashMap uptimeMapping = new HashMap(); 214 | uptimeMapping.put(Pattern.compile(".*load average:\\s+([0-9\\.]+),\\s+([0-9\\.]+),\\s+([0-9\\.]+)"), 215 | new String[]{"la1", "la5", "la15"}); 216 | allCommands.put("uptime", new UnixCommand(new String[]{"uptime"}, commandTypes.REGEXDIM, defaultignores, 0, uptimeMapping)); 217 | 218 | allMetrics.put(CommandMetricUtils.mungeString("uptime", "la1"), new MetricDetail("LoadAverage", "1 Minute", "load", metricTypes.NORMAL, 1)); 219 | allMetrics.put(CommandMetricUtils.mungeString("uptime", "la5"), new MetricDetail("LoadAverage", "5 Minute", "load", metricTypes.NORMAL, 1)); 220 | allMetrics.put(CommandMetricUtils.mungeString("uptime", "la15"), new MetricDetail("LoadAverage", "15 Minute", "load", metricTypes.NORMAL, 1)); 221 | 222 | HashMap vmstatMapping = new HashMap(); 223 | vmstatMapping.put(Pattern.compile("\\s*(\\d+)\\s+(.*)"), new String[]{kColumnMetricName, kColumnMetricValue}); 224 | allCommands.put("vmstat", new UnixCommand(new String[]{"vmstat", "-s"}, commandTypes.REGEXDIM, defaultignores, 0, vmstatMapping)); 225 | 226 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "total address trans. faults"),new MetricDetail("Faults", "Address Translation Faults", "faults", metricTypes.DELTA, 1)); 227 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "page ins"),new MetricDetail("Page", "VMM Page-Ins", "pages", metricTypes.DELTA, 1)); 228 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "page outs"),new MetricDetail("Page", "VMM Page-Outs", "pages", metricTypes.DELTA, 1)); 229 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "zero filled pages faults"),new MetricDetail("Faults", "Zero-filled Pages Faults", "faults", metricTypes.DELTA, 1)); 230 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "executable filled pages faults"),new MetricDetail("Faults", "Executable Filled Pages Faults", "faults", metricTypes.DELTA, 1)); 231 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "pages examined by clock"),new MetricDetail("Page", "Examined by clock", "pages", metricTypes.DELTA, 1)); 232 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "pages freed by the clock"),new MetricDetail("Page", "Freed by clock", "pages", metricTypes.DELTA, 1)); 233 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "cpu context switches"),new MetricDetail("Faults", "CPU Context Switches", "switches", metricTypes.DELTA, 1)); 234 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "device interrupts"),new MetricDetail("Faults", "Device Interrupts", "interrupts", metricTypes.DELTA, 1)); 235 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "software interrupts"),new MetricDetail("Faults", "Software Interrupts", "interrupts", metricTypes.DELTA, 1)); 236 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "decrementer interrupts"),new MetricDetail("Faults", "Decrementer Interrupts", "interrupts", metricTypes.DELTA, 1)); 237 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "syscalls"),new MetricDetail("Faults", "System Calls", "calls", metricTypes.DELTA, 1)); 238 | 239 | HashMap vmstatThreadMapping = new HashMap(); 240 | vmstatThreadMapping.put(Pattern.compile("\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+).*"), 241 | new String[]{"r","b","p","w"}); 242 | allCommands.put("VmstatThreads", new UnixCommand(new String[]{"vmstat", "-I", "-W", "1", "1"}, commandTypes.REGEXDIM, defaultignores, 0, vmstatThreadMapping)); 243 | 244 | allMetrics.put(CommandMetricUtils.mungeString("VmstatThreads", "r"), new MetricDetail("KernelThreads", "Runnable", "threads", metricTypes.NORMAL, 1)); 245 | allMetrics.put(CommandMetricUtils.mungeString("VmstatThreads", "b"), new MetricDetail("KernelThreads", "In Wait Queue", "threads", metricTypes.NORMAL, 1)); 246 | allMetrics.put(CommandMetricUtils.mungeString("VmstatThreads", "p"), new MetricDetail("KernelThreads", "Waiting for Device IO", "threads", metricTypes.NORMAL, 1)); 247 | allMetrics.put(CommandMetricUtils.mungeString("VmstatThreads", "w"), new MetricDetail("KernelThreads", "Waiting for File IO", "threads", metricTypes.NORMAL, 1)); 248 | 249 | /* 250 | * OLD vmstat command 251 | * replaced by "vmstat -s" with deltas to find per-interval values 252 | * and "vmstat -IW 1 1" for Kernel Thread values 253 | HashMap vmstatMapping = new HashMap(); 254 | vmstatMapping.put(Pattern.compile("\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)" + 255 | "\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+).*"), 256 | new String[]{"r","b","avm","fre","re","pi","po","fr","sr","cy","in","sy","cs"}); 257 | allCommands.put("vmstat", new UnixCommand(new String[]{"vmstat", kExecutionDelay, "1"}, commandTypes.REGEXDIM, defaultignores, 0, vmstatMapping)); 258 | 259 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "r"), new MetricDetail("KernelThreads", "Runnable", "threads", metricTypes.NORMAL, 1)); 260 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "b"), new MetricDetail("KernelThreads", "In Wait Queue", "threads", metricTypes.NORMAL, 1)); 261 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "avm"), new MetricDetail("Memory", "Active", "pages", metricTypes.NORMAL, getPageSize())); 262 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "fre"), new MetricDetail("Memory", "Free", "pages", metricTypes.NORMAL, getPageSize())); 263 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "re"), new MetricDetail("Page", "Reclaimed", "pages", metricTypes.NORMAL, 1)); 264 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "pi"), new MetricDetail("Page", "Paged In", "pages", metricTypes.NORMAL, 1)); 265 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "po"), new MetricDetail("Page", "Paged Out", "pages", metricTypes.NORMAL, 1)); 266 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "fr"), new MetricDetail("Page", "Freed", "pages", metricTypes.NORMAL, 1)); 267 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "sr"), new MetricDetail("Page", "Scanned By Page-Replacement", "pages", metricTypes.NORMAL, 1)); 268 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "cy"), new MetricDetail("Page", "Clock Cycles By Page-Replacement", "cycles", metricTypes.NORMAL, 1)); 269 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "in"), new MetricDetail("Faults", "Device Interrupts", "interrupts", metricTypes.NORMAL, 1)); 270 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "sy"), new MetricDetail("Faults", "System Calls", "threads", metricTypes.NORMAL, 1)); 271 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "cs"), new MetricDetail("Faults", "Context Switches", "switches", metricTypes.NORMAL, 1)); 272 | */ 273 | 274 | allCommands.put("VmstatTotals", new UnixCommand(new String[]{"vmstat", "-s"}, commandTypes.SIMPLEDIM, defaultignores)); 275 | } 276 | } 277 | -------------------------------------------------------------------------------- /src/com/chocolatefactory/newrelic/plugins/unix/LinuxMetrics.java: -------------------------------------------------------------------------------- 1 | package com.chocolatefactory.newrelic.plugins.unix; 2 | 3 | import java.util.Arrays; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.regex.Pattern; 7 | 8 | import com.chocolatefactory.newrelic.plugins.utils.CommandMetricUtils; 9 | import com.chocolatefactory.newrelic.plugins.utils.MetricDetail; 10 | import com.chocolatefactory.newrelic.plugins.utils.MetricDetail.metricTypes; 11 | 12 | public class LinuxMetrics extends UnixMetrics { 13 | 14 | public static final String kDefaultAgentName = "Linux"; 15 | public List linuxvmstatignores = Arrays.asList(13, 14, 15, 16, 17); 16 | 17 | public LinuxMetrics() { 18 | 19 | // Linux doesn't use "pagesize" command 20 | super(new String[]{"getconf","PAGESIZE"}); 21 | 22 | /* 23 | * Parser & declaration for 'df' command 24 | */ 25 | HashMap dfMapping = new HashMap(); 26 | dfMapping.put(Pattern.compile("\\s*(\\S+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)%.*"), 27 | new String[]{kColumnMetricDiskName, "1024-blocks", "Used", "Available", "Capacity"}); 28 | allCommands.put("df", new UnixCommand(new String[]{"df","-Pk", "-x iso9660", "-x cdfs", "-x hsfs"}, commandTypes.REGEXDIM, defaultignores, 0, dfMapping)); 29 | allMetrics.put(CommandMetricUtils.mungeString("df", "1024-blocks"), new MetricDetail("Disk", "Total", "kb", metricTypes.NORMAL, 1)); 30 | allMetrics.put(CommandMetricUtils.mungeString("df", "Used"), new MetricDetail("Disk", "Used", "kb", metricTypes.NORMAL, 1)); 31 | allMetrics.put(CommandMetricUtils.mungeString("df", "Available"), new MetricDetail("Disk", "Free", "kb", metricTypes.NORMAL, 1)); 32 | allMetrics.put(CommandMetricUtils.mungeString("df", "Capacity"), new MetricDetail("Disk", "Used", "percent", metricTypes.NORMAL, 1)); 33 | 34 | /* 35 | * Parser & declaration for 'diskstats' command 36 | */ 37 | HashMap diskstatsMapping = new HashMap(); 38 | diskstatsMapping.put(Pattern.compile("\\d+\\s+\\d+\\s+(\\S+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)" + 39 | "\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)"), 40 | new String[]{kColumnMetricPrefix, "reads", "readsmerged", "sectorsread", "readtime", "writes", "writesmerged", "sectorswritten", "writetime", "inprogress", "iotime", "iotime_weighted"}); 41 | 42 | allCommands.put("diskstats", new UnixCommand(new String[]{"cat","/proc/diskstats"}, commandTypes.REGEXDIM, defaultignores, 0, diskstatsMapping)); 43 | 44 | allMetrics.put(CommandMetricUtils.mungeString("diskstats", "reads"), new MetricDetail("DiskIO", "Reads Per Interval", "transfers", metricTypes.DELTA, 1)); 45 | allMetrics.put(CommandMetricUtils.mungeString("diskstats", "readsmerged"), new MetricDetail("DiskIO", "Reads Merged Per Interval", "transfers", metricTypes.DELTA, 1)); 46 | allMetrics.put(CommandMetricUtils.mungeString("diskstats", "sectorsread"), new MetricDetail("DiskIO", "Sectors Read Per Interval", "sectors", metricTypes.DELTA, 1)); 47 | allMetrics.put(CommandMetricUtils.mungeString("diskstats", "readtime"), new MetricDetail("DiskIO", "Time Spent Reading", "ms", metricTypes.DELTA, 1)); 48 | allMetrics.put(CommandMetricUtils.mungeString("diskstats", "writes"), new MetricDetail("DiskIO", "Writes Per Interval", "transfers", metricTypes.DELTA, 1)); 49 | allMetrics.put(CommandMetricUtils.mungeString("diskstats", "writesmerged"), new MetricDetail("DiskIO", "Writes Merged Per Interval", "transfers", metricTypes.DELTA, 1)); 50 | allMetrics.put(CommandMetricUtils.mungeString("diskstats", "sectorswritten"), new MetricDetail("DiskIO", "Sectors Per Interval", "sectors", metricTypes.DELTA, 1)); 51 | allMetrics.put(CommandMetricUtils.mungeString("diskstats", "writetime"), new MetricDetail("DiskIO", "Time Spent Writing", "ms", metricTypes.DELTA, 1)); 52 | allMetrics.put(CommandMetricUtils.mungeString("diskstats", "inprogress"), new MetricDetail("IO", "IO In progress", "count", metricTypes.DELTA, 1)); 53 | allMetrics.put(CommandMetricUtils.mungeString("diskstats", "iotime"), new MetricDetail("IO", "Time Spent on IO", "ms", metricTypes.DELTA, 1)); 54 | allMetrics.put(CommandMetricUtils.mungeString("diskstats", "iotime_weighted"), new MetricDetail("IO", "Time Spent on IO (Weighted)", "ms", metricTypes.DELTA, 1)); 55 | 56 | /* 57 | * Parsers & declaration for 'iostat' command 58 | */ 59 | HashMap iostatMapping = new HashMap(); 60 | iostatMapping.put(Pattern.compile("\\s*([0-9\\.]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+)"), 61 | new String[]{"%user", "%nice", "%system", "%iowait", "%steal", "%idle"}); 62 | iostatMapping.put(Pattern.compile("(\\S+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+" 63 | + "([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)"), 64 | new String[]{kColumnMetricPrefix, "rrqm-s", "wrqm-s", "r-s", "w-s", "rkB-s", "wkB-s", "avgrq-sz", "avgqu-sz", "await", "svctm", "%util"}); 65 | iostatMapping.put(Pattern.compile("(\\S+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+" 66 | + "([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)\\s+([\\d\\.]+)"), 67 | new String[]{kColumnMetricPrefix, "rrqm-s", "wrqm-s", "r-s", "w-s", "rkB-s", "wkB-s", "avgrq-sz", "avgqu-sz", "await", "r_await", "w_await", "svctm", "%util"}); 68 | allCommands.put("iostat", new UnixCommand(new String[]{"iostat", "-k", "-x", kExecutionDelay, kExecutionCount}, commandTypes.REGEXDIM, defaultignores, 0, iostatMapping)); 69 | 70 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "%user"), new MetricDetail("CPU", "User", "percent", metricTypes.NORMAL, 1)); 71 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "%nice"), new MetricDetail("CPU", "Nice", "percent", metricTypes.NORMAL, 1)); 72 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "%system"), new MetricDetail("CPU", "System", "percent", metricTypes.NORMAL, 1)); 73 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "%iowait"), new MetricDetail("CPU", "Waiting", "percent", metricTypes.NORMAL, 1)); 74 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "%steal"), new MetricDetail("CPU", "Stolen", "percent", metricTypes.NORMAL, 1)); 75 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "%idle"), new MetricDetail("CPU", "Idle", "percent", metricTypes.NORMAL, 1)); 76 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "rrqm-s"), new MetricDetail("DiskIO", "Queued Merged Read Requests", "requests", metricTypes.NORMAL, 1)); 77 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "wrqm-s"), new MetricDetail("DiskIO", "Queued Merged Write Requests", "requests", metricTypes.NORMAL, 1)); 78 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "r-s"), new MetricDetail("DiskIO", "Reads Per Second", "transfers", metricTypes.NORMAL, 1)); 79 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "w-s"), new MetricDetail("DiskIO", "Writes Per Second", "transfers", metricTypes.NORMAL, 1)); 80 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "rkB-s"), new MetricDetail("DiskIO", "Data Read Per Second", "kb", metricTypes.NORMAL, 1)); 81 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "wkB-s"), new MetricDetail("DiskIO", "Data Written Per Second", "kb", metricTypes.NORMAL, 1)); 82 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "avgrq-sz"), new MetricDetail("DiskIO", "Average Request Size", "sectors", metricTypes.NORMAL, 1)); 83 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "avgqu-sz"), new MetricDetail("DiskIO", "Average Requests Queued", "requests", metricTypes.NORMAL, 1)); 84 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "await"), new MetricDetail("DiskIO", "Average Response Time", "ms", metricTypes.NORMAL, 1)); 85 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "r_await"), new MetricDetail("DiskIO", "Average Response Time (read)", "ms", metricTypes.NORMAL, 1)); 86 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "w_await"), new MetricDetail("DiskIO", "Average Response Time (write)", "ms", metricTypes.NORMAL, 1)); 87 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "svctm"), new MetricDetail("DiskIO", "Total Request Time", "ms", metricTypes.NORMAL, 1)); 88 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "%util"), new MetricDetail("DiskIO", "Percentage of Time Busy", "percent", metricTypes.NORMAL, 1)); 89 | 90 | /* 91 | * Parser & declaration for "NetworkIO" 92 | */ 93 | HashMap networkIOMapping = new HashMap(); 94 | networkIOMapping.put(Pattern.compile("\\/sys\\/class\\/net\\/[\\w\\d]+\\/statistics\\/([\\w_]+):(\\d+)"), 95 | new String[]{kColumnMetricName, kColumnMetricValue}); 96 | allCommands.put("NetworkIO", new UnixCommand(new String[]{"grep", "-r", ".", "/sys/class/net/" + kMemberPlaceholder + "/statistics", "2>&1"}, 97 | commandTypes.REGEXLISTDIM, defaultignores, 0, networkIOMapping)); 98 | 99 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "collisions"), new MetricDetail("Network", "Collisions", "packets", metricTypes.DELTA, 1)); 100 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "multicast"), new MetricDetail("Network", "Multicast", "packets", metricTypes.DELTA, 1)); 101 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "rx_bytes"), new MetricDetail("Network", "Receive/Bytes", "bytes", metricTypes.DELTA, 1)); 102 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "rx_compressed"), new MetricDetail("Network", "Receive/Compressed", "packets", metricTypes.DELTA, 1)); 103 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "rx_crc_errors"), new MetricDetail("Network", "Receive/CRC Errors", "errors", metricTypes.DELTA, 1)); 104 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "rx_dropped"), new MetricDetail("Network", "Receive/Dropped", "packets", metricTypes.DELTA, 1)); 105 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "rx_errors"), new MetricDetail("Network", "Receive/Errors", "errors", metricTypes.DELTA, 1)); 106 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "rx_fifo_errors"), new MetricDetail("Network", "Receive/FIFO Errors", "errors", metricTypes.DELTA, 1)); 107 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "rx_frame_errors"), new MetricDetail("Network", "Receive/Frame Errors", "errors", metricTypes.DELTA, 1)); 108 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "rx_length_errors"), new MetricDetail("Network", "Receive/Length Errors", "errors", metricTypes.DELTA, 1)); 109 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "rx_missed_errors"), new MetricDetail("Network", "Receive/Missed Errors", "errors", metricTypes.DELTA, 1)); 110 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "rx_over_errors"), new MetricDetail("Network", "Receive/Overrun Errors", "errors", metricTypes.DELTA, 1)); 111 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "rx_packets"), new MetricDetail("Network", "Receive/Packets", "packets", metricTypes.DELTA, 1)); 112 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "tx_aborted_errors"), new MetricDetail("Network", "Transmit/Aborted Errors", "errors", metricTypes.DELTA, 1)); 113 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "tx_bytes"), new MetricDetail("Network", "Transmit/Bytes", "bytes", metricTypes.DELTA, 1)); 114 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "tx_carrier_errors"), new MetricDetail("Network", "Transmit/Carrier Errors", "errors", metricTypes.DELTA, 1)); 115 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "tx_compressed"), new MetricDetail("Network", "Transmit/Compressed", "packets", metricTypes.DELTA, 1)); 116 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "tx_dropped"), new MetricDetail("Network", "Transmit/Dropped", "packets", metricTypes.DELTA, 1)); 117 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "tx_errors"), new MetricDetail("Network", "Transmit/Errors", "errors", metricTypes.DELTA, 1)); 118 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "tx_fifo_errors"), new MetricDetail("Network", "Transmit/FIFO Errors", "errors", metricTypes.DELTA, 1)); 119 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "tx_heartbeat_errors"), new MetricDetail("Network", "Transmit/Heartbeat Errors", "errors", metricTypes.DELTA, 1)); 120 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "tx_packets"), new MetricDetail("Network", "Transmit/Packets", "packets", metricTypes.DELTA, 1)); 121 | allMetrics.put(CommandMetricUtils.mungeString("networkio", "tx_window_errors"), new MetricDetail("Network", "Transmit/Window Errors", "errors", metricTypes.DELTA, 1)); 122 | 123 | /* 124 | * Parser & declaration for 'netstat' command 125 | * ** NOT USED IN FAVOR OF NETWORKIO ** 126 | */ 127 | HashMap netstatMapping = new HashMap(); 128 | netstatMapping.put(Pattern.compile("(\\w+\\d*)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)" 129 | + "\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+).*"), 130 | new String[]{kColumnMetricPrefix, "MTU", "Met", "RX-OK", "RX-ERR", "RX-DRP", "RX-OVR", "TX-OK", "TX-ERR", "TX-DRP", "TX-OVR"}); 131 | allCommands.put("netstat", new UnixCommand(new String[]{"netstat", "-i"}, commandTypes.REGEXDIM, defaultignores, 0, netstatMapping)); 132 | 133 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "MTU"), new MetricDetail("Network", "MTU", "packets", metricTypes.NORMAL, 1)); 134 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Met"), new MetricDetail("Network", "Metric", "metric", metricTypes.NORMAL, 1)); 135 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "RX-OK"), new MetricDetail("Network", "Receive/Packets", "packets", metricTypes.DELTA, 1)); 136 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "RX-ERR"), new MetricDetail("Network", "Receive/Errors", "errors", metricTypes.DELTA, 1)); 137 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "RX-DRP"), new MetricDetail("Network", "Receive/Dropped", "packets", metricTypes.DELTA, 1)); 138 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "RX-OVR"), new MetricDetail("Network", "Receive/Overrun Errors", "errors", metricTypes.DELTA, 1)); 139 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "TX-OK"), new MetricDetail("Network", "Transmit/Packets", "packets", metricTypes.DELTA, 1)); 140 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "TX-ERR"), new MetricDetail("Network", "Transmit/Errors", "errors", metricTypes.DELTA, 1)); 141 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "TX-DRP"), new MetricDetail("Network", "Transmit/Drops", "packets", metricTypes.DELTA, 1)); 142 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "TX-OVR"), new MetricDetail("Network", "Transmit/Overrun Errors", "errors", metricTypes.DELTA, 1)); 143 | 144 | /* 145 | * Parser & declaration for 'ps' command 146 | */ 147 | HashMap psMapping = new HashMap(); 148 | psMapping.put(Pattern.compile("([0-9\\.]+)\\s+([0-9\\.]+)\\s+(\\d+)\\s+(.*)"), 149 | new String[]{"%CPU", "%MEM", "RSS", kColumnMetricProcessName}); 150 | allCommands.put("ps", new UnixCommand(new String[]{"ps", "-ewwo", "%cpu,%mem,rss,command"}, 151 | commandTypes.REGEXDIM, defaultignores, 0, psMapping)); 152 | 153 | allMetrics.put(CommandMetricUtils.mungeString("ps", kColumnMetricProcessName), new MetricDetail("Processes", "Instance Count", "processes", metricTypes.INCREMENT, 1)); 154 | allMetrics.put(CommandMetricUtils.mungeString("ps", "%CPU"), new MetricDetail("Processes", "Aggregate CPU", "percent", metricTypes.INCREMENT, 1)); 155 | allMetrics.put(CommandMetricUtils.mungeString("ps", "%MEM"), new MetricDetail("Processes", "Aggregate Memory", "percent", metricTypes.INCREMENT, 1)); 156 | allMetrics.put(CommandMetricUtils.mungeString("ps", "RSS"), new MetricDetail("Processes", "Aggregate Resident Size", "kb", metricTypes.INCREMENT, 1)); 157 | 158 | /* 159 | * Parsers & declaration for 'top' command 160 | */ 161 | HashMap topMapping = new HashMap(); 162 | topMapping.put(Pattern.compile("top.*load average:\\s+([0-9\\.]+),\\s+([0-9\\.]+),\\s+([0-9\\.]+)"), 163 | new String[]{"la1", "la5", "la15"}); 164 | topMapping.put(Pattern.compile("Tasks:\\s+(\\d+)\\s+total,\\s+(\\d+)\\s+running,\\s+(\\d+)\\s+sleeping,\\s+(\\d+)\\s+stopped,\\s+(\\d+)\\s+zombie"), 165 | new String[]{"proctot", "procrun", "proczzz", "procstop", "proczomb"}); 166 | topMapping.put(Pattern.compile(".*Mem:\\s+(\\d+)k\\s+total,\\s+(\\d+)k\\s+used,\\s+(\\d+)k\\s+free,\\s+(\\d+)k\\s+buffers"), 167 | new String[]{"memtot", "memused", "memfree", "membuff"}); 168 | topMapping.put(Pattern.compile(".*Swap:\\s+(\\d+)k\\s+total,\\s+(\\d+)k\\s+used,\\s+(\\d+)k\\s+free,\\s+(\\d+)k\\s+cached"), 169 | new String[]{"swaptot", "swapused", "swapfree", "swapbuff"}); 170 | topMapping.put(Pattern.compile("KiB Mem:\\s+(\\d+)\\s+total,\\s+(\\d+)\\s+used,\\s+(\\d+)\\s+free,\\s+(\\d+)\\s+buffers"), 171 | new String[]{"memtot", "memused", "memfree", "membuff"}); 172 | topMapping.put(Pattern.compile("KiB Swap:\\s+(\\d+)\\s+total,\\s+(\\d+)\\s+used,\\s+(\\d+)\\s+free,\\s+(\\d+)\\s+cached"), 173 | new String[]{"swaptot", "swapused", "swapfree", "swapbuff"}); 174 | topMapping.put(Pattern.compile("[%]*Cpu[^:]*:\\s+([\\d\\.]+)%\\s*us,\\s+([\\d\\.]+)%\\s*sy," 175 | + "\\s+([\\d\\.]+)%\\s*ni,\\s+([\\d\\.]+)%\\s*id," 176 | + "\\s+([\\d\\.]+)%\\s*wa,\\s+([\\d\\.]+)%\\s*hi," 177 | + "\\s+([\\d\\.]+)%\\s*si,\\s+([\\d\\.]+)%\\s*st"), 178 | new String[]{"cpuus", "cpusy", "cpuni", "cpuid", "cpuwa", "cpuhi", "cpusi", "cpust"}); 179 | 180 | allCommands.put("top", new UnixCommand(new String[]{"top","-b","-n","1"}, commandTypes.REGEXDIM, defaultignores, 5, topMapping)); 181 | 182 | allMetrics.put(CommandMetricUtils.mungeString("top", "la1"), new MetricDetail("LoadAverage", "1 Minute", "load", metricTypes.NORMAL, 1)); 183 | allMetrics.put(CommandMetricUtils.mungeString("top", "la5"), new MetricDetail("LoadAverage", "5 Minute", "load", metricTypes.NORMAL, 1)); 184 | allMetrics.put(CommandMetricUtils.mungeString("top", "la15"), new MetricDetail("LoadAverage", "15 Minute", "load", metricTypes.NORMAL, 1)); 185 | allMetrics.put(CommandMetricUtils.mungeString("top", "proctot"), new MetricDetail("Processes", "Total", "processes", metricTypes.NORMAL, 1)); 186 | allMetrics.put(CommandMetricUtils.mungeString("top", "procrun"), new MetricDetail("Processes", "Running", "processes", metricTypes.NORMAL, 1)); 187 | allMetrics.put(CommandMetricUtils.mungeString("top", "proczzz"), new MetricDetail("Processes", "Sleeping", "processes", metricTypes.NORMAL, 1)); 188 | allMetrics.put(CommandMetricUtils.mungeString("top", "procstop"), new MetricDetail("Processes", "Stopped", "processes", metricTypes.NORMAL, 1)); 189 | allMetrics.put(CommandMetricUtils.mungeString("top", "proczomb"), new MetricDetail("Processes", "Zombie", "processes", metricTypes.NORMAL, 1)); 190 | allMetrics.put(CommandMetricUtils.mungeString("top", "memtot"), new MetricDetail("Memory", "Total", "kb", metricTypes.NORMAL, 1)); 191 | allMetrics.put(CommandMetricUtils.mungeString("top", "memused"), new MetricDetail("Memory", "Used", "kb", metricTypes.NORMAL, 1)); 192 | allMetrics.put(CommandMetricUtils.mungeString("top", "memfree"), new MetricDetail("Memory", "Free", "kb", metricTypes.NORMAL, 1)); 193 | allMetrics.put(CommandMetricUtils.mungeString("top", "membuff"), new MetricDetail("Memory", "Buffer", "kb", metricTypes.NORMAL, 1)); 194 | allMetrics.put(CommandMetricUtils.mungeString("top", "swaptot"), new MetricDetail("MemoryDetailed", "Swap/Total", "kb", metricTypes.NORMAL, 1)); 195 | allMetrics.put(CommandMetricUtils.mungeString("top", "swapused"), new MetricDetail("MemoryDetailed", "Swap/Used", "kb", metricTypes.NORMAL, 1)); 196 | allMetrics.put(CommandMetricUtils.mungeString("top", "swapfree"), new MetricDetail("MemoryDetailed", "Swap/Free", "kb", metricTypes.NORMAL, 1)); 197 | allMetrics.put(CommandMetricUtils.mungeString("top", "swapbuff"), new MetricDetail("MemoryDetailed", "Swap/Buffer", "kb", metricTypes.NORMAL, 1)); 198 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpuus"), new MetricDetail("CPU", "User", "percent", metricTypes.NORMAL, 1)); 199 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpuni"), new MetricDetail("CPU", "Nice", "percent", metricTypes.NORMAL, 1)); 200 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpusy"), new MetricDetail("CPU", "System", "percent", metricTypes.NORMAL, 1)); 201 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpuwa"), new MetricDetail("CPU", "Waiting", "percent", metricTypes.NORMAL, 1)); 202 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpust"), new MetricDetail("CPU", "Stolen", "percent", metricTypes.NORMAL, 1)); 203 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpuid"), new MetricDetail("CPU", "Idle", "percent", metricTypes.NORMAL, 1)); 204 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpuhi"), new MetricDetail("CPU", "Interrupt-Hardware", "percent", metricTypes.NORMAL, 1)); 205 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpusi"), new MetricDetail("CPU", "Interrupt-Software", "percent", metricTypes.NORMAL, 1)); 206 | 207 | /* 208 | * Parsers & declaration for 'vmstat' command 209 | */ 210 | HashMap vmstatMapping = new HashMap(); 211 | vmstatMapping.put(Pattern.compile("\\s*(\\d+)\\s+(.*)"), new String[]{kColumnMetricName, kColumnMetricValue}); 212 | allCommands.put("vmstat", new UnixCommand(new String[]{"vmstat", "-s"}, commandTypes.REGEXDIM, defaultignores, 0, vmstatMapping)); 213 | 214 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "page swapped in"),new MetricDetail("Page", "Swapped In", "pages", metricTypes.DELTA, 1)); 215 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "page swapped out"),new MetricDetail("Page", "Swapped Out", "pages", metricTypes.DELTA, 1)); 216 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "pages paged in"),new MetricDetail("Page", "Paged In", "pages", metricTypes.DELTA, 1)); 217 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "pages paged out"),new MetricDetail("Page", "Paged Out", "pages", metricTypes.DELTA, 1)); 218 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "CPU context switches"),new MetricDetail("Faults", "CPU Context Switches", "switches", metricTypes.DELTA, 1)); 219 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "interrupts"),new MetricDetail("Faults", "Interrupts", "interrupts", metricTypes.DELTA, 1)); 220 | 221 | /* 222 | * Parsers & declaration for 'vmstat' command 223 | */ 224 | HashMap vmstatKernelMapping = new HashMap(); 225 | vmstatKernelMapping.put(Pattern.compile("\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)" 226 | + "\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)" 227 | + "\\s+(\\d+)\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+"), 228 | new String[]{"r", "b", "swpd", "free", "buff", "cache", "si", "so", "bi", "bo", "in", "cs"}); 229 | allCommands.put("VmstatKernel", new UnixCommand(new String[]{"vmstat", "-s"}, commandTypes.REGEXDIM, defaultignores, 0, vmstatKernelMapping)); 230 | 231 | allMetrics.put(CommandMetricUtils.mungeString("VmstatKernel", "r"), new MetricDetail("KernelThreads", "Runnable", "threads", metricTypes.NORMAL, 1)); 232 | allMetrics.put(CommandMetricUtils.mungeString("VmstatKernel", "b"), new MetricDetail("KernelThreads", "In Wait Queue", "threads", metricTypes.NORMAL, 1)); 233 | //allMetrics.put(CommandMetricUtils.mungeString("vmstat", "swpd"), new MetricDetail("Memory", "Swap", "kb", metricTypes.NORMAL, getPageSize()*1024)); 234 | //allMetrics.put(CommandMetricUtils.mungeString("vmstat", "free"), new MetricDetail("Memory", "Free", "kb", metricTypes.NORMAL, getPageSize()*1024)); 235 | //allMetrics.put(CommandMetricUtils.mungeString("vmstat", "buff"), new MetricDetail("Memory", "Buffer", "kb", metricTypes.NORMAL, getPageSize()*1024)); 236 | //allMetrics.put(CommandMetricUtils.mungeString("vmstat", "cache"), new MetricDetail("Memory", "Cache", "kb", metricTypes.NORMAL, getPageSize()*1024)); 237 | //allMetrics.put(CommandMetricUtils.mungeString("vmstat", "si"), new MetricDetail("Page", "Paged In", "pages", metricTypes.NORMAL, 1)); 238 | //allMetrics.put(CommandMetricUtils.mungeString("vmstat", "so"), new MetricDetail("Page", "Paged Out", "pages", metricTypes.NORMAL, 1)); 239 | //allMetrics.put(CommandMetricUtils.mungeString("vmstat", "bi"), new MetricDetail("IO", "Sent", "Blocks", metricTypes.NORMAL, 1)); 240 | //allMetrics.put(CommandMetricUtils.mungeString("vmstat", "bo"), new MetricDetail("IO", "Received", "Blocks", metricTypes.NORMAL, 1)); 241 | //allMetrics.put(CommandMetricUtils.mungeString("vmstat", "in"), new MetricDetail("Faults", "Device Interrupts", "interrupts", metricTypes.NORMAL, 1)); 242 | //allMetrics.put(CommandMetricUtils.mungeString("vmstat", "cs"), new MetricDetail("Faults", "Context Switches", "switches", metricTypes.NORMAL, 1)); 243 | /* 244 | * Skipping last 5 columns of vmstat for CPU measurement - using iostat instead. 245 | * allMetrics.put(CommandMetricUtils.mungeString("vmstat", "us"), new MetricDetail("CPU", "User", "percent", metricTypes.NORMAL, 1)); 246 | * allMetrics.put(CommandMetricUtils.mungeString("vmstat", "sy"), new MetricDetail("CPU", "System", "percent", metricTypes.NORMAL, 1)); 247 | * allMetrics.put(CommandMetricUtils.mungeString("vmstat", "id"), new MetricDetail("CPU", "Idle", "percent", metricTypes.NORMAL, 1)); 248 | * allMetrics.put(CommandMetricUtils.mungeString("vmstat", "wa"), new MetricDetail("CPU", "Waiting", "percent", metricTypes.NORMAL, 1)); 249 | * allMetrics.put(CommandMetricUtils.mungeString("vmstat", "st"), new MetricDetail("CPU", "Stolen", "percent", metricTypes.NORMAL, 1)); 250 | */ 251 | 252 | allCommands.put("VmstatTotals", new UnixCommand(new String[]{"vmstat","-s"}, commandTypes.SIMPLEDIM, defaultignores)); 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /src/com/chocolatefactory/newrelic/plugins/unix/Main.java: -------------------------------------------------------------------------------- 1 | package com.chocolatefactory.newrelic.plugins.unix; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.OutputStream; 9 | 10 | import com.newrelic.metrics.publish.Runner; 11 | import com.newrelic.metrics.publish.configuration.Config; 12 | import com.newrelic.metrics.publish.configuration.ConfigurationException; 13 | import com.chocolatefactory.newrelic.plugins.unix.UnixAgentFactory; 14 | 15 | public class Main { 16 | 17 | public static void main(String[] args) { 18 | try { 19 | checkPluginFile(); 20 | Runner runner = new Runner(); 21 | runner.add(new UnixAgentFactory()); 22 | runner.setupAndRun(); // Never returns 23 | } catch (ConfigurationException e) { 24 | System.err.println("ERROR: " + e.getMessage()); 25 | System.exit(-1); 26 | } 27 | } 28 | 29 | private static void checkPluginFile() throws ConfigurationException { 30 | File pluginConfigFile = new File(Config.getConfigDirectory() + File.separator + "plugin.json"); 31 | if(!pluginConfigFile.exists()) { 32 | System.err.println("WARNING: " + pluginConfigFile.toString() + " does not exist"); 33 | String thisOS = System.getProperty("os.name").toLowerCase().trim(); 34 | String thisVer = System.getProperty("os.version").trim(); 35 | 36 | if(thisOS.contains("os x")) { 37 | thisOS = "osx"; 38 | } else if(thisOS.contains("sunos")) { 39 | if(thisVer.equals("5.10")) { 40 | thisOS = "solaris_10"; 41 | } else if(thisVer.equals("5.11")) { 42 | thisOS = "solaris_11"; 43 | } else { 44 | throw new ConfigurationException("This version of Solaris isn't supported: " + thisVer); 45 | } 46 | } 47 | 48 | File specificPluginConfigFile = new File(Config.getConfigDirectory() + File.separator + "plugin.json." + thisOS); 49 | if(specificPluginConfigFile.exists()) { 50 | System.err.println("Attempting to copy plugin.json." + thisOS + " to plugin.json"); 51 | try { 52 | copyFile(specificPluginConfigFile, pluginConfigFile); 53 | System.err.println("Successfully copied plugin.json." + thisOS + " to plugin.json"); 54 | } catch(IOException ioe) { 55 | throw new ConfigurationException("Failed to copy plugin.json file for your OS: " + thisOS + "\n" + ioe.getMessage()); 56 | } 57 | } else { 58 | throw new ConfigurationException("The plugin.json file for this OS doesn't exist: " + thisOS); 59 | } 60 | } 61 | } 62 | 63 | private static void copyFile(File src, File dst) throws IOException { 64 | InputStream in = new FileInputStream(src); 65 | try { 66 | OutputStream out = new FileOutputStream(dst); 67 | try { 68 | byte[] buf = new byte[1024]; 69 | int len; 70 | while ((len = in.read(buf)) > 0) { 71 | out.write(buf, 0, len); 72 | } 73 | } finally { 74 | out.close(); 75 | } 76 | } finally { 77 | in.close(); 78 | } 79 | } 80 | } 81 | 82 | -------------------------------------------------------------------------------- /src/com/chocolatefactory/newrelic/plugins/unix/OSXMetrics.java: -------------------------------------------------------------------------------- 1 | package com.chocolatefactory.newrelic.plugins.unix; 2 | 3 | import java.util.HashMap; 4 | import java.util.regex.Pattern; 5 | 6 | import com.chocolatefactory.newrelic.plugins.utils.CommandMetricUtils; 7 | import com.chocolatefactory.newrelic.plugins.utils.MetricDetail; 8 | import com.chocolatefactory.newrelic.plugins.utils.MetricDetail.metricTypes; 9 | 10 | public class OSXMetrics extends UnixMetrics { 11 | 12 | public static final String kDefaultAgentName = "MacOSX"; 13 | 14 | public OSXMetrics() { 15 | 16 | super(); 17 | 18 | /* 19 | * Parser & declaration for 'df' command 20 | */ 21 | HashMap dfMapping = new HashMap(); 22 | dfMapping.put(Pattern.compile("\\s*(\\S+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)%.*"), 23 | new String[]{kColumnMetricDiskName, "1K-blocks", "Used", "Available", "Use%"}); 24 | allCommands.put("df", new UnixCommand(new String[]{"df","-k"}, commandTypes.REGEXDIM, defaultignores, 0, dfMapping)); 25 | allMetrics.put(CommandMetricUtils.mungeString("df", "1K-blocks"), new MetricDetail("Disk", "Total", "kb", metricTypes.NORMAL, 1)); 26 | allMetrics.put(CommandMetricUtils.mungeString("df", "Used"), new MetricDetail("Disk", "Used", "kb", metricTypes.NORMAL, 1)); 27 | allMetrics.put(CommandMetricUtils.mungeString("df", "Available"), new MetricDetail("Disk", "Free", "kb", metricTypes.NORMAL, 1)); 28 | allMetrics.put(CommandMetricUtils.mungeString("df", "Use%"), new MetricDetail("Disk", "Used", "percent", metricTypes.NORMAL, 1)); 29 | 30 | /* 31 | * Parsers & declaration for 'iostat' command 32 | */ 33 | HashMap iostatMapping = new HashMap(); 34 | iostatMapping.put(Pattern.compile("\\s*([0-9\\.]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+).*"), 35 | new String[]{"KB-t", "xfrs", "MB"}); 36 | allCommands.put("iostat", new UnixCommand(new String[]{"iostat", "-I" , "-d", kMemberPlaceholder}, commandTypes.REGEXLISTDIM, defaultignores, 0, iostatMapping)); 37 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "xfrs"), new MetricDetail("DiskIO", "Transfers Per Interval", "transfers", metricTypes.DELTA, 1)); 38 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "MB"), new MetricDetail("DiskIO", "Data Transferred Per Interval", "kb", metricTypes.DELTA, 1024)); 39 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "KB-t"), new MetricDetail("DiskIO", "Average Request Size", "kb", metricTypes.NORMAL, 1)); 40 | 41 | /* 42 | * Parser & declaration for 'netstat' command 43 | */ 44 | HashMap netstatMapping = new HashMap(); 45 | netstatMapping.put(Pattern.compile("(\\w+\\d*)\\s+\\d+\\s+\\S+\\s+\\S+\\s+" 46 | + "(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)"), 47 | new String[]{kColumnMetricPrefix, "Ipkts", "Ierrs", "Ibytes", "Opkts", "Oerrs", "Obytes", "Coll"}); 48 | allCommands.put("netstat", new UnixCommand(new String[]{"netstat", "-i", "-b"}, commandTypes.REGEXDIM, defaultignores, 0, netstatMapping)); 49 | 50 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Ipkts"), new MetricDetail("Network", "Receive/Packets", "packets", metricTypes.DELTA, 1)); 51 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Ierrs"), new MetricDetail("Network", "Receive/Errors", "errors", metricTypes.DELTA, 1)); 52 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Ibytes"), new MetricDetail("Network", "Receive/Bytes", "bytes", metricTypes.DELTA, 1)); 53 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Opkts"), new MetricDetail("Network", "Transmit/Packets", "packets", metricTypes.DELTA, 1)); 54 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Oerrs"), new MetricDetail("Network", "Transmit/Errors", "errors", metricTypes.DELTA, 1)); 55 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Obytes"), new MetricDetail("Network", "Transmit/Bytes", "bytes", metricTypes.DELTA, 1)); 56 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Coll"), new MetricDetail("Network", "Collisions", "packets", metricTypes.DELTA, 1)); 57 | 58 | /* 59 | * Parser & declaration for 'ps' command 60 | */ 61 | HashMap psMapping = new HashMap(); 62 | psMapping.put(Pattern.compile("([0-9\\.]+)\\s+([0-9\\.]+)\\s+(\\d+)\\s+(.+)"), 63 | new String[]{"%CPU", "%MEM", "RSS", kColumnMetricProcessName}); 64 | allCommands.put("ps", new UnixCommand(new String[]{"ps", "-ewwo", "%cpu,%mem,rss,args"}, 65 | commandTypes.REGEXDIM, defaultignores, 0, psMapping)); 66 | 67 | allMetrics.put(CommandMetricUtils.mungeString("ps", kColumnMetricProcessName), new MetricDetail("Processes", "Instance Count", "processes", metricTypes.INCREMENT, 1)); 68 | allMetrics.put(CommandMetricUtils.mungeString("ps", "%CPU"), new MetricDetail("Processes", "Aggregate CPU", "percent", metricTypes.INCREMENT, 1)); 69 | allMetrics.put(CommandMetricUtils.mungeString("ps", "%MEM"), new MetricDetail("Processes", "Aggregate Memory", "percent", metricTypes.INCREMENT, 1)); 70 | allMetrics.put(CommandMetricUtils.mungeString("ps", "RSS"), new MetricDetail("Processes", "Aggregate Resident Size", "kb", metricTypes.INCREMENT, 1)); 71 | 72 | /* 73 | * Parsers & declaration for 'top' command 74 | */ 75 | HashMap topMapping = new HashMap(); 76 | topMapping.put(Pattern.compile("Load Avg:\\s+([0-9\\.]+),\\s+([0-9\\.]+),\\s+([0-9\\.]+)"), 77 | new String[]{"la1", "la5", "la15"}); 78 | topMapping.put(Pattern.compile("Processes:\\s+(\\d+)\\s+total,\\s+(\\d+)\\s+running,\\s+(\\d+)\\s+stuck,\\s+(\\d+)\\s+sleeping,\\s+(\\d+)\\s+threads.*"), 79 | new String[]{"proctot", "procrun", "procstuck", "proczzz", "procthreads"}); 80 | topMapping.put(Pattern.compile("CPU usage:\\s+([0-9\\.]+)%\\s+user,\\s+([0-9\\.]+)%\\s+sys,\\s+([0-9\\.]+)%\\s+idle.*"), 81 | new String[]{"cpuuser", "cpusys", "cpuidle"}); 82 | topMapping.put(Pattern.compile("MemRegions:\\s+(\\d+)\\s+total,\\s+(\\d+)M\\s+resident,\\s+(\\d+)M\\s+private,\\s+(\\d+)M\\s+shared.*"), 83 | new String[]{"memregtot", "memregres", "memregpriv", "memregshare"}); 84 | topMapping.put(Pattern.compile("Swap:\\s+(\\d+)B\\s+\\+\\s+(\\d+)B\\s+free."), 85 | new String[]{"swapused", "swapfree"}); 86 | topMapping.put(Pattern.compile("PhysMem:\\s+(\\d+)M\\s+used\\s+.*"), 87 | new String[]{"memused"}); 88 | topMapping.put(Pattern.compile("PhysMem:\\s+(\\d+)G\\s+used\\s+.*"), 89 | new String[]{"memusedgigs"}); 90 | topMapping.put(Pattern.compile("PhysMem:\\s+\\d+[MG]{1}\\s+used\\s+\\((\\d+)M wired\\).*"), 91 | new String[]{"memwired"}); 92 | topMapping.put(Pattern.compile("PhysMem:\\s+\\d+[MG]{1}\\s+used\\s+\\((\\d+)G wired\\).*"), 93 | new String[]{"memwiredgigs"}); 94 | topMapping.put(Pattern.compile("PhysMem:\\s+\\d+[MG]{1}\\s+used\\s+\\(\\d+[MG]{1} wired\\),\\s(\\d+)M\\s+unused."), 95 | new String[]{"memfree"}); 96 | topMapping.put(Pattern.compile("PhysMem:\\s+\\d+[MG]{1}\\s+used\\s+\\(\\d+[MG]{1} wired\\),\\s(\\d+)G\\s+unused."), 97 | new String[]{"memfreegigs"}); 98 | topMapping.put(Pattern.compile("Disks:\\s+(\\d+)\\/\\d+[BKMGT]{1}\\s+read,\\s+(\\d+)\\/\\d+[BKMGT]{1}\\s+written."), 99 | new String[]{"diskreads","diskwrites"}); 100 | allCommands.put("top", new UnixCommand(new String[]{"top","-l", "1", "-n", "0", "-S"}, commandTypes.REGEXDIM, defaultignores, 0, true, topMapping)); 101 | 102 | allMetrics.put(CommandMetricUtils.mungeString("top", "la1"), new MetricDetail("LoadAverage", "1 Minute", "load", metricTypes.NORMAL, 1)); 103 | allMetrics.put(CommandMetricUtils.mungeString("top", "la5"), new MetricDetail("LoadAverage", "5 Minute", "load", metricTypes.NORMAL, 1)); 104 | allMetrics.put(CommandMetricUtils.mungeString("top", "la15"), new MetricDetail("LoadAverage", "15 Minute", "load", metricTypes.NORMAL, 1)); 105 | allMetrics.put(CommandMetricUtils.mungeString("top", "proctot"), new MetricDetail("Processes", "Total", "processes", metricTypes.NORMAL, 1)); 106 | allMetrics.put(CommandMetricUtils.mungeString("top", "procrun"), new MetricDetail("Processes", "Running", "processes", metricTypes.NORMAL, 1)); 107 | allMetrics.put(CommandMetricUtils.mungeString("top", "proczzz"), new MetricDetail("Processes", "Sleeping", "processes", metricTypes.NORMAL, 1)); 108 | allMetrics.put(CommandMetricUtils.mungeString("top", "procstuck"), new MetricDetail("Processes", "Stuck", "processes", metricTypes.NORMAL, 1)); 109 | allMetrics.put(CommandMetricUtils.mungeString("top", "procthreads"), new MetricDetail("KernelThreads", "Runnable", "threads", metricTypes.NORMAL, 1)); 110 | allMetrics.put(CommandMetricUtils.mungeString("top", "memregtot"), new MetricDetail("MemoryDetailed", "Regions/Total", "regions", metricTypes.NORMAL, 1)); 111 | allMetrics.put(CommandMetricUtils.mungeString("top", "memregres"), new MetricDetail("MemoryDetailed", "Regions/Resident", "kb", metricTypes.NORMAL, 1024)); 112 | allMetrics.put(CommandMetricUtils.mungeString("top", "memregpriv"), new MetricDetail("MemoryDetailed", "Regions/Private", "kb", metricTypes.NORMAL, 1024)); 113 | allMetrics.put(CommandMetricUtils.mungeString("top", "memregshare"), new MetricDetail("MemoryDetailed", "Regions/Shared", "kb", metricTypes.NORMAL, 1024)); 114 | allMetrics.put(CommandMetricUtils.mungeString("top", "swapused"), new MetricDetail("MemoryDetailed", "Swap/Used", "kb", metricTypes.NORMAL, 1)); 115 | allMetrics.put(CommandMetricUtils.mungeString("top", "swapfree"), new MetricDetail("MemoryDetailed", "Swap/Free", "kb", metricTypes.NORMAL, 1)); 116 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpuuser"), new MetricDetail("CPU", "User", "percent", metricTypes.NORMAL, 1)); 117 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpuidle"), new MetricDetail("CPU", "Idle", "percent", metricTypes.NORMAL, 1)); 118 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpusys"), new MetricDetail("CPU", "System", "percent", metricTypes.NORMAL, 1)); 119 | allMetrics.put(CommandMetricUtils.mungeString("top", "memused"), new MetricDetail("Memory", "Used", "kb", metricTypes.NORMAL, 1024)); 120 | allMetrics.put(CommandMetricUtils.mungeString("top", "memusedgigs"), new MetricDetail("Memory", "Used", "kb", metricTypes.NORMAL, 1048576)); 121 | allMetrics.put(CommandMetricUtils.mungeString("top", "memwired"), new MetricDetail("Memory", "Wired", "kb", metricTypes.NORMAL, 1024)); 122 | allMetrics.put(CommandMetricUtils.mungeString("top", "memwiredgigs"), new MetricDetail("Memory", "Wired", "kb", metricTypes.NORMAL, 1048576)); 123 | allMetrics.put(CommandMetricUtils.mungeString("top", "memfree"), new MetricDetail("Memory", "Free", "kb", metricTypes.NORMAL, 1024)); 124 | allMetrics.put(CommandMetricUtils.mungeString("top", "memfreegigs"), new MetricDetail("Memory", "Free", "kb", metricTypes.NORMAL, 1048576)); 125 | allMetrics.put(CommandMetricUtils.mungeString("top", "diskreads"), new MetricDetail("DiskIO", "Reads Per Interval", "reads", metricTypes.NORMAL, 1048576)); 126 | allMetrics.put(CommandMetricUtils.mungeString("top", "diskwrites"), new MetricDetail("DiskIO", "Writes Per Interval", "writes", metricTypes.NORMAL, 1048576)); 127 | 128 | HashMap vm_statMapping = new HashMap(); 129 | vm_statMapping.put(Pattern.compile("\\s*([^:]+):\\s+(\\d+)\\.*"), new String[]{kColumnMetricName, kColumnMetricValue}); 130 | allCommands.put("vm_stat", new UnixCommand(new String[]{"vm_stat"}, commandTypes.REGEXDIM, defaultignores, 0, vm_statMapping)); 131 | 132 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pages free"),new MetricDetail("Page", "Free", "pages", metricTypes.NORMAL, 1)); 133 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pages active"),new MetricDetail("Page", "Active", "pages", metricTypes.NORMAL, 1)); 134 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pages inactive"),new MetricDetail("Page", "Inactive", "pages", metricTypes.NORMAL, 1)); 135 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pages speculative"),new MetricDetail("Page", "Speculative", "pages", metricTypes.NORMAL, 1)); 136 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pages throttled"),new MetricDetail("Page", "Throttled", "pages", metricTypes.NORMAL, 1)); 137 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pages wired down"),new MetricDetail("Page", "Wired down", "pages", metricTypes.NORMAL, 1)); 138 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pages purgeable"),new MetricDetail("Page", "Purgeable", "pages", metricTypes.NORMAL, 1)); 139 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "\"Translation faults\""),new MetricDetail("Faults", "VM Translation Faults", "faults", metricTypes.DELTA, 1)); 140 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pages copy-on-write"),new MetricDetail("Page", "Copy-on-write", "pages", metricTypes.DELTA, 1)); 141 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pages zero filled"),new MetricDetail("Page", "Zero filled", "pages", metricTypes.DELTA, 1)); 142 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pages reactivated"),new MetricDetail("Page", "Reactivated", "pages", metricTypes.DELTA, 1)); 143 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pages purged"),new MetricDetail("Page", "Purged", "pages", metricTypes.DELTA, 1)); 144 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "File-backed pages"),new MetricDetail("Page", "File-backed", "pages", metricTypes.DELTA, 1)); 145 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Anonymous pages"),new MetricDetail("Page", "Anonymous", "pages", metricTypes.DELTA, 1)); 146 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pages stored in compressor"),new MetricDetail("Page", "Stored in compressor", "pages", metricTypes.DELTA, 1)); 147 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pages occupied by compressor"),new MetricDetail("Page", "Occupied by compressor", "pages", metricTypes.DELTA, 1)); 148 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Decompressions"),new MetricDetail("Page", "Decompressions", "pages", metricTypes.DELTA, 1)); 149 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Compressions"),new MetricDetail("Page", "Compressions", "pages", metricTypes.DELTA, 1)); 150 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pageins"),new MetricDetail("Page", "Paged In", "pages", metricTypes.DELTA, 1)); 151 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Pageouts"),new MetricDetail("Page", "Paged Out", "pages", metricTypes.DELTA, 1)); 152 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Swapins"),new MetricDetail("Page", "Swapped In", "pages", metricTypes.DELTA, 1)); 153 | allMetrics.put(CommandMetricUtils.mungeString("vm_stat", "Swapouts"),new MetricDetail("Page", "Swapped Out", "pages", metricTypes.DELTA, 1)); 154 | 155 | HashMap vmstatTotalsMapping = new HashMap(); 156 | vmstatTotalsMapping.put(Pattern.compile("\\s*\"*([^:\"]+)\"*:\\s+(\\d+)\\.*"), new String[]{kColumnMetricName, kColumnMetricValue}); 157 | allCommands.put("VmstatTotals", new UnixCommand(new String[]{"vm_stat"}, commandTypes.REGEXDIM, defaultignores, 0, vmstatTotalsMapping)); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/com/chocolatefactory/newrelic/plugins/unix/SolarisMetrics.java: -------------------------------------------------------------------------------- 1 | package com.chocolatefactory.newrelic.plugins.unix; 2 | 3 | import java.util.HashMap; 4 | import java.util.regex.Pattern; 5 | 6 | import com.chocolatefactory.newrelic.plugins.utils.CommandMetricUtils; 7 | import com.chocolatefactory.newrelic.plugins.utils.MetricDetail; 8 | import com.chocolatefactory.newrelic.plugins.utils.MetricDetail.metricTypes; 9 | 10 | public class SolarisMetrics extends UnixMetrics { 11 | 12 | public static final String kDefaultAgentName = "SunOS"; 13 | 14 | public SolarisMetrics() { 15 | 16 | super(); 17 | 18 | /* 19 | * Parser & declaration for 'df' command 20 | */ 21 | HashMap dfMapping = new HashMap(); 22 | dfMapping.put(Pattern.compile("\\s*(\\S+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)%.*"), 23 | new String[]{kColumnMetricDiskName, "1K-blocks", "Used", "Available", "Use%"}); 24 | allCommands.put("df", new UnixCommand(new String[]{"df","-k"}, commandTypes.REGEXDIM, defaultignores, 0, dfMapping)); 25 | allMetrics.put(CommandMetricUtils.mungeString("df", "1K-blocks"), new MetricDetail("Disk", "Total", "kb", metricTypes.NORMAL, 1)); 26 | allMetrics.put(CommandMetricUtils.mungeString("df", "Used"), new MetricDetail("Disk", "Used", "kb", metricTypes.NORMAL, 1)); 27 | allMetrics.put(CommandMetricUtils.mungeString("df", "Available"), new MetricDetail("Disk", "Free", "kb", metricTypes.NORMAL, 1)); 28 | allMetrics.put(CommandMetricUtils.mungeString("df", "Use%"), new MetricDetail("Disk", "Used", "percent", metricTypes.NORMAL, 1)); 29 | 30 | /* 31 | * Parser & declaration for 'iostat' command 32 | */ 33 | HashMap iostatMapping = new HashMap(); 34 | iostatMapping.put(Pattern.compile("\\s*([\\/\\w\\d]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+)" + 35 | "\\s+([0-9\\.]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+)\\s+([0-9\\.]+)\\s+(\\d+)\\s+(\\d+)"), 36 | new String[]{kColumnMetricPrefix,"r-i","w-i","kr-i","kw-i","wait","actv","svc_t","%w","%b"}); 37 | allCommands.put("iostat", new UnixCommand(new String[]{"iostat","-x","-I"}, commandTypes.REGEXDIM, defaultignores, 0, iostatMapping)); 38 | 39 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "r-i"), new MetricDetail("DiskIO", "Reads per Interval", "transfers", metricTypes.DELTA, 1)); 40 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "w-i"), new MetricDetail("DiskIO", "Writes per Interval", "transfers", metricTypes.DELTA, 1)); 41 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "kr-i"), new MetricDetail("DiskIO", "Data Read per Interval", "kb", metricTypes.DELTA, 1)); 42 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "kw-i"), new MetricDetail("DiskIO", "Data Written per Interval", "kb", metricTypes.DELTA, 1)); 43 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "wait"), new MetricDetail("DiskIO", "Average queue length", "transactions", metricTypes.NORMAL, 1)); 44 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "actv"), new MetricDetail("DiskIO", "Active transactions", "transactions", metricTypes.NORMAL, 1)); 45 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "svc_t"), new MetricDetail("DiskIO", "Average service time", "ms", metricTypes.NORMAL, 1)); 46 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "%w"), new MetricDetail("DiskIO", "Percentage of Time Non-Empty Queue", "percent", metricTypes.NORMAL, 1)); 47 | allMetrics.put(CommandMetricUtils.mungeString("iostat", "%b"), new MetricDetail("DiskIO", "Percentage of Time Busy", "percent", metricTypes.NORMAL, 1)); 48 | 49 | /* 50 | * Parser & declaration for 'iostat' CPU command 51 | * ** only used on Solaris 10 (Solaris 11 has 'top') ** 52 | */ 53 | HashMap iostatCPUMapping = new HashMap(); 54 | iostatCPUMapping.put(Pattern.compile("\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)"), 55 | new String[]{"us","sy","wt","id"}); 56 | allCommands.put("IostatCPU", new UnixCommand(new String[]{"iostat","-c", "1", "2"}, commandTypes.REGEXDIM, defaultignores, 0, iostatCPUMapping)); 57 | // To make this backwards-compatible with older Solaris plugin.json versions. 58 | allCommands.put("iostatCPU", new UnixCommand(new String[]{"iostat","-c", "1", "2"}, commandTypes.REGEXDIM, defaultignores, 0, iostatCPUMapping)); 59 | 60 | allMetrics.put(CommandMetricUtils.mungeString("iostatcpu", "us"), new MetricDetail("CPU", "User", "percent", metricTypes.NORMAL, 1)); 61 | allMetrics.put(CommandMetricUtils.mungeString("iostatcpu", "sy"), new MetricDetail("CPU", "System", "percent", metricTypes.NORMAL, 1)); 62 | allMetrics.put(CommandMetricUtils.mungeString("iostatcpu", "wt"), new MetricDetail("CPU", "Waiting", "percent", metricTypes.NORMAL, 1)); 63 | allMetrics.put(CommandMetricUtils.mungeString("iostatcpu", "id"), new MetricDetail("CPU", "Idle", "percent", metricTypes.NORMAL, 1)); 64 | 65 | /* 66 | * Parser & declaration for 'kstat' command for Network information 67 | */ 68 | HashMap kstatNetworkMapping = new HashMap(); 69 | kstatNetworkMapping.put(Pattern.compile("(\\w+\\d*)\\s+([0-9\\.]+)"), 70 | new String[]{kColumnMetricName, kColumnMetricValue}); 71 | allCommands.put("KstatNetwork", new UnixCommand(new String[]{"kstat", "-n", kMemberPlaceholder}, commandTypes.REGEXLISTDIM, defaultignores, 0, kstatNetworkMapping)); 72 | 73 | allMetrics.put(CommandMetricUtils.mungeString("KstatNetwork", "brdcstrcv"), new MetricDetail("Network", "Receive/Broadcast", "packets", metricTypes.DELTA, 1)); 74 | allMetrics.put(CommandMetricUtils.mungeString("KstatNetwork", "brdcstxmt"), new MetricDetail("Network", "Transmit/Broadcast", "packets", metricTypes.DELTA, 1)); 75 | allMetrics.put(CommandMetricUtils.mungeString("KstatNetwork", "collisions"), new MetricDetail("Network", "Collisions", "packets", metricTypes.DELTA, 1)); 76 | allMetrics.put(CommandMetricUtils.mungeString("KstatNetwork", "ierrors"), new MetricDetail("Network", "Receive/Errors", "errors", metricTypes.DELTA, 1)); 77 | allMetrics.put(CommandMetricUtils.mungeString("KstatNetwork", "ipackets64"), new MetricDetail("Network", "Receive/Packets", "packets", metricTypes.DELTA, 1)); 78 | allMetrics.put(CommandMetricUtils.mungeString("KstatNetwork", "multircv"), new MetricDetail("Network", "Receive/Multicast", "bytes", metricTypes.DELTA, 1)); 79 | allMetrics.put(CommandMetricUtils.mungeString("KstatNetwork", "multixmt"), new MetricDetail("Network", "Transmit/Multicast", "bytes", metricTypes.DELTA, 1)); 80 | allMetrics.put(CommandMetricUtils.mungeString("KstatNetwork", "norcvbuf"), new MetricDetail("Network", "Receive/Buffer Allocation Errors", "errors", metricTypes.DELTA, 1)); 81 | allMetrics.put(CommandMetricUtils.mungeString("KstatNetwork", "noxmtbuf"), new MetricDetail("Network", "Transmit/Buffer Allocation Errors", "errors", metricTypes.DELTA, 1)); 82 | allMetrics.put(CommandMetricUtils.mungeString("KstatNetwork", "obytes64"), new MetricDetail("Network", "Transmit/Bytes", "bytes", metricTypes.DELTA, 1)); 83 | allMetrics.put(CommandMetricUtils.mungeString("KstatNetwork", "oerrors"), new MetricDetail("Network", "Transmit/Errors", "errors", metricTypes.DELTA, 1)); 84 | allMetrics.put(CommandMetricUtils.mungeString("KstatNetwork", "opackets64"), new MetricDetail("Network", "Transmit/Packets", "packets", metricTypes.DELTA, 1)); 85 | allMetrics.put(CommandMetricUtils.mungeString("KstatNetwork", "rbytes64"), new MetricDetail("Network", "Receive/Bytes", "bytes", metricTypes.DELTA, 1)); 86 | 87 | /* 88 | * Parser & declaration for 'kstat' command for Page and Memory information 89 | * 90 | */ 91 | HashMap kstatPagesMapping = new HashMap(); 92 | kstatPagesMapping.put(Pattern.compile("unix:0:system_pages:([\\w_]+)\\s+([0-9\\.]+)"), 93 | new String[]{kColumnMetricName, kColumnMetricValue}); 94 | allCommands.put("KstatPages", new UnixCommand(new String[]{"kstat", "-p", "unix::system_pages"}, commandTypes.REGEXDIM, defaultignores, 0, kstatPagesMapping)); 95 | 96 | allMetrics.put(CommandMetricUtils.mungeString("KstatPages", "availrmem"), new MetricDetail("Page", "Available", "pages", metricTypes.DELTA, 1)); 97 | allMetrics.put(CommandMetricUtils.mungeString("KstatPages", "pagesfree"), new MetricDetail("Page", "Free", "pages", metricTypes.DELTA, 1)); 98 | allMetrics.put(CommandMetricUtils.mungeString("KstatPages", "pageslocked"), new MetricDetail("Page", "Locked", "pages", metricTypes.DELTA, 1)); 99 | allMetrics.put(CommandMetricUtils.mungeString("KstatPages", "pagestotal"), new MetricDetail("Page", "Total", "pages", metricTypes.DELTA, 1)); 100 | allMetrics.put(CommandMetricUtils.mungeString("KstatPages", "pp_kernel"), new MetricDetail("Page", "Used By Kernel", "pages", metricTypes.DELTA, 1)); 101 | allMetrics.put(CommandMetricUtils.mungeString("KstatPages", "physmem"), new MetricDetail("Memory", "Total", "kb", metricTypes.NORMAL, getPageSize()/1000)); 102 | allMetrics.put(CommandMetricUtils.mungeString("KstatPages", "freemem"), new MetricDetail("Memory", "Free", "kb", metricTypes.NORMAL, getPageSize()/1000)); 103 | 104 | 105 | /* 106 | * Parser & declaration for 'netstat' command 107 | * ** NOT USED IN FAVOR OF KSTAT ** 108 | */ 109 | HashMap netstatMapping = new HashMap(); 110 | netstatMapping.put(Pattern.compile("(\\w+\\d*)\\s+(\\d+)\\s+[\\d\\.]+\\s+[\\d\\.]+" 111 | + "\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)"), 112 | new String[]{kColumnMetricPrefix, "MTU", "Iptks", "Ierrs", "Optks", "Oerrs", "Collis", "Queue"}); 113 | allCommands.put("netstat", new UnixCommand(new String[]{"netstat", "-i", "-n"}, commandTypes.REGEXDIM, defaultignores, 0, netstatMapping)); 114 | 115 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Ipkts"), new MetricDetail("Network", "Receive/Packets", "packets", metricTypes.DELTA, 1)); 116 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Ierrs"), new MetricDetail("Network", "Receive/Errors", "packets", metricTypes.DELTA, 1)); 117 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Opkts"), new MetricDetail("Network", "Transmit/Packets", "packets", metricTypes.DELTA, 1)); 118 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Oerrs"), new MetricDetail("Network", "Transmit/Errors", "packets", metricTypes.DELTA, 1)); 119 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Collis"), new MetricDetail("Network", "Collisions", "packets", metricTypes.DELTA, 1)); 120 | allMetrics.put(CommandMetricUtils.mungeString("netstat", "Queue"), new MetricDetail("Network", "Queue", "packets", metricTypes.NORMAL, 1)); 121 | 122 | /* 123 | * Parser & declaration for 'prstat' command 124 | * ** only used on Solaris 10 (Solaris 11 has 'top') ** 125 | */ 126 | HashMap prstatMapping = new HashMap(); 127 | prstatMapping.put(Pattern.compile("Total:\\s+(\\d+)\\s+processes,\\s+(\\d+)\\s+lwps,\\s+load averages:\\s+([\\d\\.]+),\\s+([\\d\\.]+),\\s+([\\d\\.]+)"), 128 | new String[]{"procs", "lwps", "la1", "la5", "la15"}); 129 | allCommands.put("prstat", new UnixCommand(new String[]{"prstat", "-c", "1", "1"}, commandTypes.REGEXDIM, defaultignores, 0, prstatMapping)); 130 | 131 | allMetrics.put(CommandMetricUtils.mungeString("prstat", "la1"), new MetricDetail("LoadAverage", "1 Minute", "load", metricTypes.NORMAL, 1)); 132 | allMetrics.put(CommandMetricUtils.mungeString("prstat", "la5"), new MetricDetail("LoadAverage", "5 Minute", "load", metricTypes.NORMAL, 1)); 133 | allMetrics.put(CommandMetricUtils.mungeString("prstat", "la15"), new MetricDetail("LoadAverage", "15 Minute", "load", metricTypes.NORMAL, 1)); 134 | allMetrics.put(CommandMetricUtils.mungeString("prstat", "procs"), new MetricDetail("Processes", "Total", "processes", metricTypes.NORMAL, 1)); 135 | allMetrics.put(CommandMetricUtils.mungeString("prstat", "lwps"), new MetricDetail("Processes", "Lightweight", "processes", metricTypes.NORMAL, 1)); 136 | 137 | /* 138 | * Parser & declaration for 'ps' command 139 | */ 140 | HashMap psMapping = new HashMap(); 141 | psMapping.put(Pattern.compile("([0-9\\.]+)\\s+([0-9\\.]+)\\s+(\\d+)\\s+(.+)"), 142 | new String[]{"%CPU", "%MEM", "RSS", kColumnMetricProcessName}); 143 | allCommands.put("ps", new UnixCommand(new String[]{"ps", "-eo", "pcpu,pmem,rss,args"}, commandTypes.REGEXDIM, defaultignores, 0, psMapping)); 144 | 145 | allMetrics.put(CommandMetricUtils.mungeString("ps", kColumnMetricProcessName), new MetricDetail("Processes", "Instance Count", "processes", metricTypes.INCREMENT, 1)); 146 | allMetrics.put(CommandMetricUtils.mungeString("ps", "%CPU"), new MetricDetail("Processes", "Aggregate CPU", "percent", metricTypes.INCREMENT, 1)); 147 | allMetrics.put(CommandMetricUtils.mungeString("ps", "%MEM"), new MetricDetail("Processes", "Aggregate Memory", "percent", metricTypes.INCREMENT, 1)); 148 | allMetrics.put(CommandMetricUtils.mungeString("ps", "RSS"), new MetricDetail("Processes", "Aggregate Resident Size", "kb", metricTypes.INCREMENT, 1)); 149 | 150 | /* 151 | * Parser & declaration for 'swap' command 152 | */ 153 | HashMap swapMapping = new HashMap(); 154 | swapMapping.put(Pattern.compile("total:\\s+(\\d+)k\\s+bytes allocated\\s+\\+\\s+(\\d+)k\\s+reserved\\s+=\\s+(\\d+)k\\s+used,\\s+(\\d+)k\\s+available"), 155 | new String[]{"swalloc", "swres", "swused", "swavail"}); 156 | allCommands.put("swap", new UnixCommand(new String[]{"/usr/sbin/swap","-s"}, commandTypes.REGEXDIM, defaultignores, 0, swapMapping)); 157 | 158 | allMetrics.put(CommandMetricUtils.mungeString("swap", "swalloc"), new MetricDetail("MemoryDetailed/Swap", "Allocated", "kb", metricTypes.NORMAL, 1)); 159 | allMetrics.put(CommandMetricUtils.mungeString("swap", "swres"), new MetricDetail("MemoryDetailed/Swap", "Reserved", "kb", metricTypes.NORMAL, 1)); 160 | allMetrics.put(CommandMetricUtils.mungeString("swap", "swused"), new MetricDetail("MemoryDetailed/Swap", "Used", "kb", metricTypes.NORMAL, 1)); 161 | allMetrics.put(CommandMetricUtils.mungeString("swap", "swavail"), new MetricDetail("MemoryDetailed/Swap", "Available", "kb", metricTypes.NORMAL, 1)); 162 | 163 | /* 164 | * Parsers & declaration for 'top' command 165 | * ** only used on Solaris 11 (Solaris 10 does not always have 'top') ** 166 | */ 167 | HashMap topMapping = new HashMap(); 168 | topMapping.put(Pattern.compile("load averages:\\s+([0-9\\.]+),\\s+([0-9\\.]+),\\s+([0-9\\.]+);.*"), 169 | new String[]{"la1", "la5", "la15"}); 170 | topMapping.put(Pattern.compile("([0-9\\.]+)\\s+processes:\\s+([0-9]+)\\s+sleeping,\\s+([0-9]+) on cpu"), 171 | new String[]{"proctot", "procslp", "proccpu"}); 172 | topMapping.put(Pattern.compile("Memory:\\s+([0-9]+)M\\s+phys mem,\\s+([0-9]+)M\\s+free mem,\\s+([0-9]+)M\\s+total swap,\\s+([0-9]+)M\\s+free swap"), 173 | new String[]{"memphys", "memfree", "swaptot", "swapfree"}); 174 | topMapping.put(Pattern.compile("CPU states:\\s+([0-9\\.]+)%\\s+idle,\\s+([0-9\\.]+)%\\s+user,\\s+([0-9\\.]+)%\\s+kernel,\\s+([0-9\\.]+)%\\s+iowait,\\s+([0-9\\.]+)%\\s+swap"), 175 | new String[]{"cpuidle", "cpuuser", "cpukern", "cpuiowait", "cpuswap"}); 176 | allCommands.put("top", new UnixCommand(new String[]{"top","-b"}, commandTypes.REGEXDIM, defaultignores, 5, topMapping)); 177 | 178 | allMetrics.put(CommandMetricUtils.mungeString("top", "la1"), new MetricDetail("LoadAverage", "1 Minute", "load", metricTypes.NORMAL, 1)); 179 | allMetrics.put(CommandMetricUtils.mungeString("top", "la5"), new MetricDetail("LoadAverage", "5 Minute", "load", metricTypes.NORMAL, 1)); 180 | allMetrics.put(CommandMetricUtils.mungeString("top", "la15"), new MetricDetail("LoadAverage", "15 Minute", "load", metricTypes.NORMAL, 1)); 181 | allMetrics.put(CommandMetricUtils.mungeString("top", "proctot"), new MetricDetail("Processes", "Total", "processes", metricTypes.NORMAL, 1)); 182 | allMetrics.put(CommandMetricUtils.mungeString("top", "procslp"), new MetricDetail("Processes", "Sleeping", "processes", metricTypes.NORMAL, 1)); 183 | allMetrics.put(CommandMetricUtils.mungeString("top", "proccpu"), new MetricDetail("Processes", "On CPU", "processes", metricTypes.NORMAL, 1)); 184 | allMetrics.put(CommandMetricUtils.mungeString("top", "memphys"), new MetricDetail("MemoryDetailed", "Physical/Total", "kb", metricTypes.NORMAL, 1024)); 185 | allMetrics.put(CommandMetricUtils.mungeString("top", "memfree"), new MetricDetail("MemoryDetailed", "Physical/Free", "kb", metricTypes.NORMAL, 1024)); 186 | allMetrics.put(CommandMetricUtils.mungeString("top", "swaptot"), new MetricDetail("MemoryDetailed", "Swap/Total On Disk", "kb", metricTypes.NORMAL, 1024)); 187 | allMetrics.put(CommandMetricUtils.mungeString("top", "swapfree"), new MetricDetail("MemoryDetailed", "Swap/Free On Disk", "kb", metricTypes.NORMAL, 1024)); 188 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpuidle"), new MetricDetail("CPU", "Idle", "percent", metricTypes.NORMAL, 1)); 189 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpuuser"), new MetricDetail("CPU", "User", "percent", metricTypes.NORMAL, 1)); 190 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpukern"), new MetricDetail("CPU", "Kernel", "percent", metricTypes.NORMAL, 1)); 191 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpuiowait"), new MetricDetail("CPU", "IOWait", "percent", metricTypes.NORMAL, 1)); 192 | allMetrics.put(CommandMetricUtils.mungeString("top", "cpuswap"), new MetricDetail("CPU", "Swap", "percent", metricTypes.NORMAL, 1)); 193 | 194 | /* 195 | * Parsers & declaration for 'vmstat' command to get threads and memory 196 | */ 197 | HashMap vmstatThreadsMapping = new HashMap(); 198 | // vmstatThreadsMemoryMapping.put(Pattern.compile("\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)" 199 | // + "\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+[-]{0,1}(\\d+)" 200 | // + "\\s+[-]{0,1}(\\d+)\\s+[-]{0,1}(\\d+)\\s+[-]{0,1}(\\d+)\\s+(\\d+)" 201 | // + "\\s+(\\d+)\\s+(\\d+).*"), 202 | // new String[]{"r","b","w","swap","free","re","mf","pi","po","fr", 203 | // "de","sr","d0","d1","d2","d3","in","sy","cs"}); 204 | vmstatThreadsMapping.put(Pattern.compile("\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+).*"), 205 | new String[]{"r","b","w","swap"}); 206 | allCommands.put("VmstatThreadsMemory", new UnixCommand(new String[]{"vmstat", "1", "2"}, commandTypes.REGEXDIM, defaultignores, 0, vmstatThreadsMapping)); 207 | 208 | allMetrics.put(CommandMetricUtils.mungeString("VmstatThreadsMemory", "r"), new MetricDetail("KernelThreads", "Runnable", "threads", metricTypes.NORMAL, 1)); 209 | allMetrics.put(CommandMetricUtils.mungeString("VmstatThreadsMemory", "b"), new MetricDetail("KernelThreads", "In Wait Queue", "threads", metricTypes.NORMAL, 1)); 210 | allMetrics.put(CommandMetricUtils.mungeString("VmstatThreadsMemory", "w"), new MetricDetail("KernelThreads", "Swapped", "threads", metricTypes.NORMAL, 1)); 211 | allMetrics.put(CommandMetricUtils.mungeString("VmstatThreadsMemory", "swap"), new MetricDetail("Memory", "Swap", "kb", metricTypes.NORMAL, 1)); 212 | 213 | /* 214 | * Replaced with kstat pages calculations for memory (seemingly more accurate) 215 | allMetrics.put(CommandMetricUtils.mungeString("VmstatThreadsMemory", "free"), new MetricDetail("Memory", "Free", "kb", metricTypes.NORMAL, 1)); 216 | allMetrics.put(CommandMetricUtils.mungeString("VmstatThreadsMemory", "memsize"), new MetricDetail("Memory", "Total", "kb", metricTypes.NORMAL, 1024)); 217 | */ 218 | 219 | /* 220 | * Replaced with deltas from vmstat -s (more accurate, no waiting!) 221 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "re"), new MetricDetail("Page", "Reclaimed", "pages", metricTypes.NORMAL, 1)); 222 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "mf"), new MetricDetail("Page", "Page Faults", "pages", metricTypes.NORMAL, 1)); 223 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "pi"), new MetricDetail("Page", "Paged In", "pages", metricTypes.NORMAL, 1)); 224 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "po"), new MetricDetail("Page", "Paged Out", "pages", metricTypes.NORMAL, 1)); 225 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "fr"), new MetricDetail("Page", "Freed", "pages", metricTypes.NORMAL, 1)); 226 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "de"), new MetricDetail("Page", "Anticipated Short-term Shortfall", "kb", metricTypes.NORMAL, 1)); 227 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "sr"), new MetricDetail("Page", "Pages Scanned by Clock Algorithm", "pages", metricTypes.NORMAL, 1)); 228 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "d0"), new MetricDetail("Disk", "disk0/Operations per Second", "ops", metricTypes.NORMAL, 1)); 229 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "d1"), new MetricDetail("Disk", "disk1/Operations per Second", "ops", metricTypes.NORMAL, 1)); 230 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "d2"), new MetricDetail("Disk", "disk2/Operations per Second", "ops", metricTypes.NORMAL, 1)); 231 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "d3"), new MetricDetail("Disk", "disk3/Operations per Second", "ops", metricTypes.NORMAL, 1)); 232 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "in"), new MetricDetail("Faults", "Device Interrupts", "interrupts", metricTypes.NORMAL, 1)); 233 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "sy"), new MetricDetail("Faults", "System Calls", "threads", metricTypes.NORMAL, 1)); 234 | allMetrics.put(CommandMetricUtils.mungeString("vmstat", "cs"), new MetricDetail("Faults", "Context Switches", "switches", metricTypes.NORMAL, 1)); 235 | */ 236 | 237 | /* 238 | * Parses & declaration for 'vmstat' command to get pages & faults 239 | */ 240 | 241 | HashMap vmstatPagesFaultsMapping = new HashMap(); 242 | vmstatPagesFaultsMapping.put(Pattern.compile("\\s*(\\d+)\\s+(.*)"), 243 | new String[]{kColumnMetricValue, kColumnMetricName}); 244 | allCommands.put("VmstatPagesFaults", new UnixCommand(new String[]{"vmstat", "-s"}, commandTypes.REGEXDIM, defaultignores, 0, vmstatPagesFaultsMapping)); 245 | 246 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "pages swapped in"), new MetricDetail("Page", "Swapped In", "pages", metricTypes.DELTA, 1)); 247 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "pages swapped out"), new MetricDetail("Page", "Swapped Out", "pages", metricTypes.DELTA, 1)); 248 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "total address trans. faults taken"), new MetricDetail("Faults", "Address Translation", "faults", metricTypes.DELTA, 1)); 249 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "pages paged in"), new MetricDetail("Page", "Paged In", "pages", metricTypes.DELTA, 1)); 250 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "pages paged out"), new MetricDetail("Page", "Paged Out", "pages", metricTypes.DELTA, 1)); 251 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "micro (hat) faults"), new MetricDetail("Faults", "Micro (hat)", "faults", metricTypes.DELTA, 1)); 252 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "minor (as) faults"), new MetricDetail("Faults", "Minor (as)", "faults", metricTypes.DELTA, 1)); 253 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "major faults"), new MetricDetail("Faults", "Major", "faults", metricTypes.DELTA, 1)); 254 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "copy-on-write faults"), new MetricDetail("Faults", "Copy-on-write", "faults", metricTypes.DELTA, 1)); 255 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "zero fill page faults"), new MetricDetail("Faults", "Zero Fill Page", "faults", metricTypes.DELTA, 1)); 256 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "cpu context switches"), new MetricDetail("Faults", "CPU Context Switches", "Faults", metricTypes.DELTA, 1)); 257 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "device interrupts"), new MetricDetail("Faults", "Device Interrupts", "faults", metricTypes.DELTA, 1)); 258 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "traps"), new MetricDetail("Faults", "Traps", "faults", metricTypes.DELTA, 1)); 259 | allMetrics.put(CommandMetricUtils.mungeString("VmstatPagesFaults", "system calls"), new MetricDetail("Faults", "System Calls", "Faults", metricTypes.DELTA, 1)); 260 | 261 | allCommands.put("VmstatTotals", new UnixCommand(new String[]{"vmstat","-s"}, commandTypes.SIMPLEDIM, defaultignores)); 262 | } 263 | } 264 | -------------------------------------------------------------------------------- /src/com/chocolatefactory/newrelic/plugins/unix/UnixAgent.java: -------------------------------------------------------------------------------- 1 | package com.chocolatefactory.newrelic.plugins.unix; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.HashMap; 6 | import java.util.HashSet; 7 | import java.util.Iterator; 8 | import java.util.Map; 9 | import java.util.Map.Entry; 10 | import java.util.regex.Matcher; 11 | import java.util.regex.Pattern; 12 | 13 | import com.chocolatefactory.newrelic.plugins.unix.UnixMetrics; 14 | import com.chocolatefactory.newrelic.plugins.unix.UnixMetrics.UnixCommand; 15 | import com.chocolatefactory.newrelic.plugins.utils.CommandMetricUtils; 16 | import com.chocolatefactory.newrelic.plugins.utils.MetricDetail; 17 | import com.chocolatefactory.newrelic.plugins.utils.MetricOutput; 18 | import com.newrelic.metrics.publish.util.Logger; 19 | import com.newrelic.metrics.publish.Agent; 20 | 21 | public class UnixAgent extends Agent { 22 | 23 | // Required for New Relic Plugins 24 | public static final String kAgentVersion = "3.6.4"; 25 | public static final String kAgentGuid = "com.chocolatefactory.newrelic.plugins.unix"; 26 | 27 | boolean isDebug = false; 28 | UnixMetrics unixMetrics; 29 | HashMap metricOutput = new HashMap(); 30 | String commandName; 31 | String hostName = ""; 32 | 33 | HashSet members; 34 | UnixCommand thisCommand = null; 35 | private static final Logger logger = Logger.getLogger(UnixAgent.class); 36 | 37 | public UnixAgent(UnixMetrics umetrics, HashMap instance) { 38 | 39 | super(kAgentGuid, kAgentVersion); 40 | 41 | hostName = (String)instance.get("hostname"); 42 | commandName = (String)instance.get("command"); 43 | isDebug = (Boolean)instance.get("debug"); 44 | String[] diskCommand = (String[])instance.get("dcommand"); 45 | String diskRegex = (String)instance.get("dregex"); 46 | String[] interfaceCommand = (String[])instance.get("icommand"); 47 | String interfaceRegex = (String)instance.get("iregex"); 48 | 49 | logger.debug("Instance Configuration:" + 50 | "\ncommand: " + commandName + 51 | "\ndebug: " + isDebug + 52 | "\nhostname: " + hostName); 53 | 54 | unixMetrics = umetrics; 55 | if (unixMetrics.allCommands.containsKey(commandName)) { 56 | thisCommand = unixMetrics.allCommands.get(commandName); 57 | if(thisCommand.getType() == UnixMetrics.commandTypes.REGEXLISTDIM) { 58 | if (thisCommand.getCommand()[0] == "iostat") { 59 | logger.debug("Running " + thisCommand.getCommand().toString() + " to get list of disks."); 60 | Pattern diskPattern = Pattern.compile(diskRegex); 61 | getMembers(diskCommand, diskPattern); 62 | } else { 63 | logger.debug("Running " + thisCommand.getCommand().toString() + " to get list of interfaces."); 64 | Pattern interfacePattern = Pattern.compile(interfaceRegex); 65 | getMembers(interfaceCommand, interfacePattern); 66 | } 67 | } 68 | } else { 69 | logger.error("Unix Agent does not support this command for your OS: "+ commandName); 70 | return; 71 | } 72 | } 73 | 74 | @Override 75 | public String getAgentName() { 76 | return hostName; 77 | } 78 | 79 | @Override 80 | public void pollCycle() { 81 | ArrayList commandReader = null; 82 | if (thisCommand == null) { 83 | logger.error("Unix Agent experienced an error initializing: " + commandName); 84 | return; 85 | } 86 | 87 | try { 88 | switch(thisCommand.getType()) { 89 | case REGEXLISTDIM: 90 | for(String thismember : members) { 91 | commandReader = CommandMetricUtils.executeCommand( 92 | CommandMetricUtils.replaceInArray(thisCommand.getCommands(), 93 | UnixMetrics.kMemberPlaceholder, thismember)); 94 | CommandMetricUtils.parseRegexMetricOutput(commandName, 95 | thisCommand.getLineMappings(), thismember, 96 | thisCommand.getLineLimit(), thisCommand.isCheckAllRegex(), 97 | metricOutput, unixMetrics.allMetrics, commandReader); 98 | } 99 | reportMetrics(); 100 | break; 101 | case REGEXDIM: 102 | commandReader = CommandMetricUtils.executeCommand(thisCommand.getCommands()); 103 | CommandMetricUtils.parseRegexMetricOutput(commandName, 104 | thisCommand.getLineMappings(), "", 105 | thisCommand.getLineLimit(), thisCommand.isCheckAllRegex(), 106 | metricOutput, unixMetrics.allMetrics, commandReader); 107 | CommandMetricUtils.addSummaryMetrics(metricOutput); 108 | reportMetrics(); 109 | break; 110 | case SIMPLEDIM: 111 | commandReader = CommandMetricUtils.executeCommand(thisCommand.getCommands()); 112 | reportMetricsSimple(CommandMetricUtils.parseSimpleMetricOutput(commandName, commandReader)); 113 | break; 114 | default: 115 | logger.error("Command Type " + thisCommand.getType().toString() + " is invalid."); 116 | return; 117 | } 118 | } catch (Exception e) { 119 | logger.error("Error: Parsing of " + Arrays.toString(thisCommand.getCommand()) + " could not be completed."); 120 | logger.debug(e.getMessage()); 121 | } 122 | } 123 | 124 | public void reportMetrics() { 125 | if(isDebug) { 126 | logger.info("Debug enabled, no metrics will be sent."); 127 | } 128 | for(String thisMetricKey : metricOutput.keySet()) { 129 | MetricOutput thisMetric = metricOutput.get(thisMetricKey); 130 | // Only report current metrics. Stale metrics will be cleaned out afterward. 131 | if (thisMetric.isCurrent()) { 132 | MetricDetail thisMetricDetail = thisMetric.getMetricDetail(); 133 | logger.debug(CommandMetricUtils.mungeString(thisMetricDetail.getPrefix(), 134 | CommandMetricUtils.mungeString(thisMetric.getNamePrefix(), thisMetricDetail.getName())) + 135 | ", " + thisMetric.getValue() + " " + thisMetricDetail.getUnits()); 136 | if(!isDebug) { 137 | reportMetric(CommandMetricUtils.mungeString( 138 | CommandMetricUtils.mungeString(thisMetricDetail.getPrefix(), thisMetric.getNamePrefix()), 139 | thisMetricDetail.getName()), thisMetricDetail.getUnits(), thisMetric.getValue()); 140 | } 141 | } 142 | } 143 | // After metrics are all reported, reset "current" list and clear out stale metrics 144 | metricOutput = CommandMetricUtils.resetCurrentMetrics(metricOutput); 145 | } 146 | 147 | public void getMembers(String[] command, Pattern memberPattern) { 148 | ArrayList membersReader = CommandMetricUtils.executeCommand(command); 149 | 150 | this.members = new HashSet(); 151 | try { 152 | for (String line : membersReader) { 153 | Matcher lineMatch = memberPattern.matcher(line); 154 | if (lineMatch.matches()) { 155 | members.add(lineMatch.group(1)); 156 | } 157 | } 158 | } catch (Exception e) { 159 | logger.error("Error: Parsing of " + Arrays.toString(command) + "could not be completed."); 160 | e.printStackTrace(); 161 | } 162 | logger.debug("Members found: " + members); 163 | } 164 | 165 | public void reportMetricsSimple(HashMap outputMetrics) { 166 | if(isDebug) { 167 | logger.info("Debug enabled, no metrics will be sent."); 168 | } 169 | Iterator> outputIterator = outputMetrics.entrySet().iterator(); 170 | while (outputIterator.hasNext()) { 171 | Map.Entry pairs = outputIterator.next(); 172 | String metricType = CommandMetricUtils.getSimpleMetricType( 173 | pairs.getKey().substring(pairs.getKey().lastIndexOf("/") + 1)); 174 | logger.debug(pairs.getKey() + ", " + pairs.getValue() + " " + metricType); 175 | if(!isDebug) { 176 | reportMetric(pairs.getKey(), metricType, pairs.getValue()); 177 | } 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/com/chocolatefactory/newrelic/plugins/unix/UnixAgentFactory.java: -------------------------------------------------------------------------------- 1 | package com.chocolatefactory.newrelic.plugins.unix; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import com.newrelic.metrics.publish.Agent; 7 | import com.newrelic.metrics.publish.AgentFactory; 8 | import com.newrelic.metrics.publish.configuration.Config; 9 | import com.newrelic.metrics.publish.configuration.ConfigurationException; 10 | import com.newrelic.metrics.publish.util.Logger; 11 | 12 | public class UnixAgentFactory extends AgentFactory { 13 | 14 | private static final String kDefaultServerName = "unixserver"; 15 | Boolean debug; 16 | Map global_properties; 17 | private static final Logger logger = Logger.getLogger(UnixAgentFactory.class); 18 | UnixMetrics umetrics; 19 | HashMap agentInstanceConfigs; 20 | 21 | public UnixAgentFactory() { 22 | super(); 23 | logger.info("Unix Agent version: " + UnixAgent.kAgentVersion); 24 | global_properties = Config.getValue("global"); 25 | if (global_properties != null) { 26 | logger.debug("Global configurations found in plugin.json."); 27 | } else { 28 | logger.debug("No global configurations found in plugin.json." + 29 | "\nYou're probably using an old OR customized version of plugin.json." + 30 | "\nEither of which is OK!"); 31 | global_properties = new HashMap(); 32 | } 33 | agentInstanceConfigs = new HashMap(); 34 | 35 | } 36 | 37 | @Override 38 | public Agent createConfiguredAgent(Map properties) throws ConfigurationException { 39 | 40 | String os, command, hostname, iregex, dregex; 41 | String[] dcommand, icommand; 42 | 43 | // Setting agent instance configurations based on plugin.json 44 | // NOTE: Per-instance properties take precedence over global properties 45 | 46 | if (properties.containsKey("debug")) { 47 | debug = (Boolean) properties.get("debug"); 48 | } else if (global_properties.containsKey("debug")) { 49 | debug = (Boolean) global_properties.get("debug"); 50 | } else { 51 | debug = false; 52 | } 53 | 54 | if (properties.containsKey("OS") && !((String) properties.get("OS")).toLowerCase().equals("auto")) { 55 | os = ((String) properties.get("OS")).toLowerCase(); 56 | } else if (global_properties.containsKey("OS") && !((String) global_properties.get("OS")).toLowerCase().equals("auto")) { 57 | os = ((String) global_properties.get("OS")).toLowerCase(); 58 | } else { 59 | os = System.getProperty("os.name").toLowerCase(); 60 | } 61 | 62 | if(properties.containsKey("hostname") && !((String)properties.get("hostname")).toLowerCase().equals("auto")) { 63 | hostname = ((String) properties.get("hostname")); 64 | } else if (global_properties.containsKey("hostname") && !((String)global_properties.get("hostname")).toLowerCase().equals("auto")) { 65 | hostname = ((String) global_properties.get("hostname")); 66 | } else { 67 | try { 68 | hostname = java.net.InetAddress.getLocalHost().getHostName(); 69 | } catch (Exception e) { 70 | logger.error("Naming failed: " + e.toString()); 71 | logger.error("Applying default server name (" + kDefaultServerName + ") to this server"); 72 | hostname = kDefaultServerName; 73 | } 74 | } 75 | 76 | logger.info("Host OS: " + os); 77 | logger.info("Hostname: " + hostname); 78 | 79 | command = ((String) properties.get("command")); 80 | 81 | if(os.contains("linux")) { 82 | umetrics = new LinuxMetrics(); 83 | dcommand = new String[]{}; 84 | dregex = ""; 85 | icommand = new String[]{"ip","link","show"}; 86 | iregex = "\\d+:\\s+(\\w+\\d*):.*"; 87 | } else if (os.contains("aix")) { 88 | umetrics = new AIXMetrics(); 89 | dcommand = new String[]{}; 90 | dregex = ""; 91 | icommand = new String[]{"/usr/sbin/ifconfig", "-a"}; 92 | iregex = "(\\w+\\d*):\\s+flags.*.*"; 93 | } else if (os.contains("sunos")) { 94 | umetrics = new SolarisMetrics(); 95 | dcommand = new String[]{}; 96 | dregex = ""; 97 | icommand = new String[]{"/usr/sbin/ifconfig", "-a"}; 98 | iregex = "(\\w+\\d*):\\d*:*\\s+flags.*"; 99 | } else if (os.toLowerCase().contains("os x") || os.toLowerCase().contains("osx")) { 100 | umetrics = new OSXMetrics(); 101 | dcommand = new String[]{"diskutil", "list"}; 102 | dregex = "\\/dev\\/(\\w+\\d*)\\s+\\([\\w\\s,]+\\):.*"; 103 | icommand = new String[]{"ifconfig", "-a"}; 104 | iregex = "(\\w+\\d*):\\s+flags.*"; 105 | } else { 106 | logger.error("Unix Agent could not detect an OS version that it supports."); 107 | logger.error("Host OS detected: " + os); 108 | return null; 109 | } 110 | 111 | agentInstanceConfigs.put("os", os); 112 | agentInstanceConfigs.put("command", command); 113 | agentInstanceConfigs.put("debug", debug); 114 | agentInstanceConfigs.put("hostname", hostname); 115 | agentInstanceConfigs.put("dcommand", dcommand); 116 | agentInstanceConfigs.put("dregex", dregex); 117 | agentInstanceConfigs.put("icommand", icommand); 118 | agentInstanceConfigs.put("iregex", iregex); 119 | 120 | return new UnixAgent(umetrics, agentInstanceConfigs); 121 | } 122 | } -------------------------------------------------------------------------------- /src/com/chocolatefactory/newrelic/plugins/unix/UnixMetrics.java: -------------------------------------------------------------------------------- 1 | package com.chocolatefactory.newrelic.plugins.unix; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.regex.Pattern; 7 | 8 | import com.chocolatefactory.newrelic.plugins.utils.CommandMetricUtils; 9 | import com.chocolatefactory.newrelic.plugins.utils.MetricDetail; 10 | 11 | public abstract class UnixMetrics { 12 | 13 | public static final String kCategoryMetricName="Component"; 14 | public static final String kDeltaMetricName="delta"; 15 | public static final String kOverviewMetricName="overview"; 16 | public static final String kDefaultMetricType="value"; 17 | public static final int kDefaultLineLimit = 0; 18 | public static final int kMetricInterval = 60; 19 | public static final String kExecutionDelay = Integer.toString(kMetricInterval / 2); 20 | public static final String kExecutionCount = "2"; 21 | public static final char kMetricTreeDivider='/'; 22 | public static final float kGigabytesToBytes=1073741824; 23 | public static final float kMegabytesToBytes=1048576; 24 | 25 | public static final String kColumnMetricPrefix = "THIS_IS_THE_PREFIX_OF_A_METRIC_NAME"; 26 | public static final String kColumnMetricProcessName = "THIS_IS_A_PROCESS_NAME_TO_BE_COUNTED"; 27 | public static final String kColumnMetricDiskName = "THIS_IS_A_DISK_NAME"; 28 | public static final String kColumnMetricName = "THIS_IS_THE_LAST_PART_OF_A_METRIC_NAME"; 29 | public static final String kColumnMetricValue = "THIS_IS_THE_ACTUAL_METRIC_VALUE"; 30 | public static final String kMemberPlaceholder = "THIS_IS_A_MEMBER_PLACEHOLDER"; 31 | public static final String kColumnIgnore = "THIS_COLUMN_WILL_BE_IGNORED"; 32 | 33 | // COMPLEXDIM: multiple metrics per line, can have words in value lines 34 | // MULTIDIM: multiple metrics per line, can only have numbers (or dashes) in line 35 | // SINGLEDIM: single metric per line (usually "name value") 36 | public static enum commandTypes{REGEXLISTDIM, REGEXDIM, SIMPLEDIM}; 37 | 38 | public HashMap allMetrics; 39 | public HashMap allCommands; 40 | // Use defaultignores in "new UnixCommand(...)" when retrieving all columns of a table, 41 | // or when retrieving single-dimensional metrics (1 metric per line) 42 | public List defaultignores; 43 | 44 | private int pageSize; 45 | String[] pageSizeCommand = {"pagesize"}; 46 | 47 | public void setPageSize() { 48 | int ps = 0; 49 | for(String line : CommandMetricUtils.executeCommand(pageSizeCommand)) { 50 | try { 51 | ps = Integer.parseInt(line.trim()); 52 | break; 53 | } catch (NumberFormatException e) { 54 | ps = 0; 55 | } 56 | } 57 | pageSize = ps; 58 | } 59 | 60 | public int getPageSize() { 61 | return pageSize; 62 | } 63 | 64 | public UnixMetrics() { 65 | setPageSize(); 66 | allMetrics = new HashMap(); 67 | allCommands = new HashMap(); 68 | defaultignores = new ArrayList(); 69 | } 70 | 71 | public UnixMetrics(String[] psc) { 72 | pageSizeCommand = psc; 73 | setPageSize(); 74 | allMetrics = new HashMap(); 75 | allCommands = new HashMap(); 76 | defaultignores = new ArrayList(); 77 | } 78 | 79 | class UnixCommand { 80 | // private String[] command; 81 | private ArrayList commands; 82 | private commandTypes type; 83 | private List skipColumns; 84 | private HashMap lineMappings; 85 | private int lineLimit; 86 | private boolean checkAllRegex = false; 87 | 88 | UnixCommand(ArrayList tcs, commandTypes tt, List sc, int ll, HashMap lm) { 89 | setCommands(tcs); 90 | setType(tt); 91 | setSkipColumns(sc); 92 | setLineLimit(ll); 93 | setLineMappings(lm); 94 | } 95 | 96 | UnixCommand(ArrayList tcs, commandTypes tt, List sc, int ll, boolean re, HashMap lm) { 97 | this(tcs, tt, sc, ll, lm); 98 | setCheckAllRegex(re); 99 | } 100 | 101 | UnixCommand(String[] tc, commandTypes tt, List sc, int ll, HashMap lm) { 102 | setCommand(tc); 103 | setType(tt); 104 | setSkipColumns(sc); 105 | setLineLimit(ll); 106 | setLineMappings(lm); 107 | } 108 | 109 | UnixCommand(String[] tc, commandTypes tt, List sc, int ll, boolean re, HashMap lm) { 110 | this(tc, tt, sc, ll, lm); 111 | setCheckAllRegex(re); 112 | } 113 | 114 | UnixCommand(String[] tc, commandTypes tt, List sc) { 115 | this(tc, tt, sc, kDefaultLineLimit, null); 116 | } 117 | 118 | public String[] getCommand() { 119 | return commands.get(0); 120 | } 121 | public void setCommand(String[] command) { 122 | commands = new ArrayList(); 123 | this.commands.add(command); 124 | } 125 | 126 | public commandTypes getType() { 127 | return type; 128 | } 129 | public void setType(commandTypes type) { 130 | this.type = type; 131 | } 132 | 133 | public List getSkipColumns() { 134 | return skipColumns; 135 | } 136 | 137 | public void setSkipColumns(List skipColumns) { 138 | this.skipColumns = skipColumns; 139 | } 140 | 141 | public HashMap getLineMappings() { 142 | return lineMappings; 143 | } 144 | 145 | public void setLineMappings(HashMap lineMappings) { 146 | if(lineMappings != null) 147 | this.lineMappings = lineMappings; 148 | } 149 | 150 | public int getLineLimit() { 151 | return lineLimit; 152 | } 153 | 154 | public void setLineLimit(int lineLimit) { 155 | this.lineLimit = lineLimit; 156 | } 157 | 158 | public boolean isCheckAllRegex() { 159 | return checkAllRegex; 160 | } 161 | 162 | public void setCheckAllRegex(boolean checkAllRegex) { 163 | this.checkAllRegex = checkAllRegex; 164 | } 165 | 166 | public ArrayList getCommands() { 167 | return commands; 168 | } 169 | 170 | public void setCommands(ArrayList commands) { 171 | this.commands = commands; 172 | } 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /src/com/chocolatefactory/newrelic/plugins/utils/CommandMetricUtils.java: -------------------------------------------------------------------------------- 1 | package com.chocolatefactory.newrelic.plugins.utils; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileReader; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.InputStreamReader; 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | import java.util.regex.Matcher; 14 | import java.util.regex.Pattern; 15 | 16 | import com.chocolatefactory.newrelic.plugins.unix.UnixAgent; 17 | import com.chocolatefactory.newrelic.plugins.unix.UnixMetrics; 18 | import com.chocolatefactory.newrelic.plugins.utils.MetricDetail.metricTypes; 19 | import com.newrelic.metrics.publish.util.Logger; 20 | 21 | public class CommandMetricUtils { 22 | 23 | public static final String kPluginJarName = "newrelic_unix_plugin"; 24 | 25 | private static Pattern dashesPattern = Pattern.compile("\\s*[\\w-]+(\\s+[-]+)+(\\s[\\w-]*)*"); 26 | private static Pattern singleMetricLinePattern = Pattern.compile("\\S*(\\d+)\\s+([\\w-%\\(\\)])(\\s{0,1}[\\w-%\\(\\)])*"); 27 | private static final Logger logger = Logger.getLogger(UnixAgent.class); 28 | 29 | public static void addSummaryMetrics(HashMap currentMetrics) throws Exception { 30 | String metricName = null, metricUnits = null, metricPrefix = "Summary"; 31 | double metricValue = 0.0, memFree = 0.0, memUsed = 0.0, memTotal = 0.0; 32 | boolean memFreeSet = false, memUsedSet = false, memTotalSet = false; 33 | HashMap newMetrics = new HashMap(); 34 | 35 | for (MetricOutput thisMetric : currentMetrics.values()) { 36 | String thisMetricName = thisMetric.getMetricDetail().getName(); 37 | String thisMetricPrefix = thisMetric.getMetricDetail().getPrefix(); 38 | double thisMetricValue = thisMetric.getValue().doubleValue(); 39 | if(thisMetricPrefix.equals("CPU") && thisMetricName.equals("Idle")) { 40 | metricValue = 100 - thisMetricValue; 41 | metricName = "CPU Utilization"; 42 | metricUnits = "%"; 43 | } else if(thisMetricPrefix.equals("Disk") && thisMetricName.equals("Used") 44 | && !thisMetric.getMetricDetail().getUnits().equals("kb") && thisMetricValue > metricValue) { 45 | metricValue = thisMetricValue; 46 | metricName = "Fullest Disk"; 47 | metricUnits = "%"; 48 | } else if(thisMetricPrefix.startsWith("Memory") && !thisMetricPrefix.startsWith("MemoryDetailed") && !thisMetricName.startsWith("Swap") 49 | && thisMetric.getMetricDetail().getUnits().equals("kb")) { 50 | if (thisMetric.getMetricDetail().getName().endsWith("Free")) { 51 | memFreeSet = true; 52 | memFree = thisMetricValue; 53 | } else if (thisMetric.getMetricDetail().getName().endsWith("Used")) { 54 | memUsedSet = true; 55 | memUsed = thisMetricValue; 56 | } else if (thisMetric.getMetricDetail().getName().endsWith("Total")) { 57 | memTotalSet = true; 58 | memTotal = thisMetricValue; 59 | } 60 | } 61 | 62 | if(metricName != null && metricUnits != null) { 63 | newMetrics.put(mungeString(metricPrefix, metricName), 64 | new MetricOutput(new MetricDetail(metricPrefix, metricName, metricUnits, metricTypes.NORMAL, 1), 65 | "", roundNumber(metricValue, 2))); 66 | metricName = null; 67 | metricUnits = null; 68 | } 69 | } 70 | 71 | if((memUsedSet && memFreeSet) || (memUsedSet && memTotalSet) || (memFreeSet && memTotalSet)) { 72 | metricName = "Memory Utilization"; 73 | metricUnits = "%"; 74 | if(memFreeSet && memTotalSet) { 75 | metricValue = (1 - (memFree / memTotal)) * 100; 76 | logger.debug("Mem Free: " + memFree); 77 | logger.debug("Mem Total: " + memTotal); 78 | } else if (memUsedSet && memTotalSet) { 79 | metricValue = (memUsed / memTotal) * 100; 80 | logger.debug("Mem Used: " + memUsed); 81 | logger.debug("Mem Total: " + memTotal); 82 | } else { 83 | metricValue = (memUsed / (memFree + memUsed)) * 100; 84 | logger.debug("Mem Free: " + memFree); 85 | logger.debug("Mem Used: " + memUsed); 86 | } 87 | 88 | logger.debug("Mem Utilization: " + metricValue); 89 | 90 | if(metricName != null && metricUnits != null) { 91 | newMetrics.put(mungeString(metricPrefix, metricName), 92 | new MetricOutput(new MetricDetail(metricPrefix, metricName, metricUnits, metricTypes.NORMAL, 1), 93 | "", roundNumber(metricValue, 2))); 94 | } 95 | } 96 | 97 | if (!newMetrics.isEmpty()) { 98 | currentMetrics.putAll(newMetrics); 99 | } 100 | } 101 | 102 | public static ArrayList executeCommand(ArrayList commands) { 103 | return executeCommand(commands, false); 104 | } 105 | 106 | public static ArrayList executeCommand(ArrayList commands, Boolean useFile) { 107 | ArrayList al = new ArrayList(); 108 | for(int i=0; i< commands.size(); i++) { 109 | al.addAll(executeCommand(commands.get(i), useFile)); 110 | } 111 | return al; 112 | } 113 | 114 | public static ArrayList executeCommand(String[] command) { 115 | return executeCommand(command, false); 116 | } 117 | 118 | public static ArrayList executeCommand(String[] command, Boolean useFile) { 119 | BufferedReader br = null; 120 | ArrayList al = new ArrayList(); 121 | String line = null; 122 | 123 | if (useFile) { 124 | File commandFile = new File(command + ".out"); 125 | CommandMetricUtils.logger.debug("Opening file: " 126 | + commandFile.getAbsolutePath()); 127 | if (!commandFile.exists()) { 128 | CommandMetricUtils.logger.error("Error: " 129 | + commandFile.getAbsolutePath() + " does not exist."); 130 | } else if (!commandFile.isFile()) { 131 | CommandMetricUtils.logger.error("Error: " 132 | + commandFile.getAbsolutePath() + " is not a file."); 133 | } else { 134 | try { 135 | br = new BufferedReader(new FileReader(commandFile)); 136 | while((line = br.readLine()) != null) { 137 | al.add(line); 138 | } 139 | } catch (Exception e) { 140 | CommandMetricUtils.logger.error("Error: " 141 | + commandFile.getAbsolutePath() 142 | + " does not exist."); 143 | e.printStackTrace(); 144 | } finally { 145 | try { 146 | br.close(); 147 | } catch (IOException e) { 148 | // If we can't close, then it's probably closed. 149 | } 150 | } 151 | } 152 | } else { 153 | Process proc = null; 154 | try { 155 | if (command != null) { 156 | CommandMetricUtils.logger.debug("Begin execution of " 157 | + Arrays.toString(command)); 158 | ProcessBuilder pb = new ProcessBuilder(command) 159 | .redirectErrorStream(true); 160 | proc = pb.start(); 161 | br = new BufferedReader(new InputStreamReader( 162 | proc.getInputStream())); 163 | while((line = br.readLine()) != null) { 164 | al.add(line); 165 | logger.debug(" Line: " + line); 166 | } 167 | proc.waitFor(); 168 | if(br != null) { 169 | br.close(); 170 | } 171 | if(proc != null) { 172 | proc.getOutputStream().close(); 173 | proc.getErrorStream().close(); 174 | proc.getInputStream().close(); 175 | } 176 | } else { 177 | CommandMetricUtils.logger.error("Error: command was null."); 178 | } 179 | } catch (Exception e) { 180 | CommandMetricUtils.logger.error("Error: Execution of " 181 | + Arrays.toString(command) + " failed."); 182 | e.printStackTrace(); 183 | } finally { 184 | try { 185 | if(br != null) { 186 | br.close(); 187 | } 188 | if(proc != null) { 189 | proc.getOutputStream().close(); 190 | proc.getErrorStream().close(); 191 | proc.getInputStream().close(); 192 | } 193 | } catch (Exception e) { 194 | // If we can't close, then it's probably closed. 195 | } 196 | } 197 | } 198 | return al; 199 | } 200 | 201 | public static String getSimpleMetricType(String metricInput) { 202 | if (metricInput.contains("percentage")) { 203 | return "%"; 204 | } else { 205 | for (String thisKeyword : metricInput.split("\\s")) { 206 | if (thisKeyword.endsWith("s")) { 207 | return thisKeyword; 208 | } 209 | } 210 | } 211 | return "ms"; 212 | } 213 | 214 | private static void insertMetric(HashMap currentMetrics, 215 | HashMap metricDeets, String metricName, 216 | String metricPrefix, String metricValueString) { 217 | 218 | String fullMetricName; 219 | double metricValue; 220 | // Set Metric names to lower-case to limit headache of OS version differences 221 | String metricNameLower = metricName.toLowerCase(); 222 | 223 | try { 224 | metricValue = Double.parseDouble(metricValueString); 225 | } catch (NumberFormatException e) { 226 | // If not a number, don't insert (return from method) 227 | return; 228 | } 229 | 230 | if (!metricPrefix.isEmpty()) { 231 | fullMetricName = CommandMetricUtils.mungeString(metricPrefix, metricNameLower); 232 | } else { 233 | fullMetricName = metricNameLower; 234 | } 235 | 236 | if (currentMetrics.containsKey(fullMetricName)) { 237 | MetricOutput thisMetric = currentMetrics.get(fullMetricName); 238 | thisMetric.setValue(metricValue); 239 | thisMetric.setCurrent(true); 240 | currentMetrics.put(fullMetricName, thisMetric); 241 | } else if (metricDeets.containsKey(metricNameLower)) { 242 | currentMetrics.put(fullMetricName, 243 | new MetricOutput(metricDeets.get(metricNameLower), metricPrefix, metricValue)); 244 | } else if (metricDeets.containsKey(metricName)) { 245 | currentMetrics.put(fullMetricName, 246 | new MetricOutput(metricDeets.get(metricName), metricPrefix, metricValue)); 247 | } else { 248 | currentMetrics.put(fullMetricName, new MetricOutput( 249 | new MetricDetail(metricPrefix, metricName, UnixMetrics.kDefaultMetricType, MetricDetail.metricTypes.NORMAL, 1), 250 | metricPrefix, metricValue)); 251 | } 252 | } 253 | 254 | public static String mungeString(String str1, String str2) { 255 | if (str1.isEmpty()) { 256 | return str2; 257 | } else if (str2.isEmpty()) { 258 | return str1; 259 | } else { 260 | return str1 + UnixMetrics.kMetricTreeDivider + str2; 261 | } 262 | } 263 | 264 | public static void parseRegexMetricOutput(String thisCommand, 265 | HashMap lineMappings, String metricPrefix, 266 | int lineLimit, boolean checkAllRegex, HashMap currentMetrics, 267 | HashMap metricDeets, 268 | ArrayList commandOutput) throws Exception { 269 | 270 | int lineCount = 0; 271 | lineloop: for(String line : commandOutput) { 272 | regexloop: for (Map.Entry lineMapping : lineMappings.entrySet()) { 273 | Pattern lineRegex = lineMapping.getKey(); 274 | String[] lineColumns = lineMapping.getValue(); 275 | Matcher lineMatch = lineRegex.matcher(line.trim()); 276 | if (lineMatch.matches()) { 277 | logger.debug("Matched: " + line); 278 | String thisMetricPrefix = metricPrefix; 279 | String thisMetricName = ""; 280 | String thisMetricValueString = ""; 281 | 282 | // Loop through columns of regexed line twice 283 | // First loop - get metric prefixes 284 | for (int l = 0; l < lineColumns.length; l++) { 285 | if(lineColumns[l] == UnixMetrics.kColumnMetricPrefix) { 286 | String thisPrefix = lineMatch.group(l + 1); 287 | thisMetricPrefix = CommandMetricUtils.mungeString(thisMetricPrefix, thisPrefix.replaceAll("/", "-")); 288 | } else if(lineColumns[l] == UnixMetrics.kColumnMetricDiskName) { 289 | String thisPrefix = lineMatch.group(l + 1); 290 | thisMetricPrefix = CommandMetricUtils.mungeString( 291 | thisMetricPrefix, thisPrefix.substring(thisPrefix.lastIndexOf('/') + 1)); 292 | } else if(lineColumns[l] == UnixMetrics.kColumnMetricProcessName) { 293 | String thisPrefix = lineMatch.group(l + 1); 294 | if(thisPrefix.contains(UnixAgent.kAgentGuid) || thisPrefix.contains(kPluginJarName)) { 295 | thisMetricPrefix = CommandMetricUtils.mungeString( 296 | thisMetricPrefix, kPluginJarName); 297 | } else { 298 | String processCommand = thisPrefix.split("\\s+")[0]; 299 | if (processCommand.startsWith("[") && processCommand.endsWith("]")) { 300 | thisMetricPrefix = CommandMetricUtils.mungeString( 301 | thisMetricPrefix, processCommand.replace("]","").replace("[", "").split("/")[0]); 302 | } else { 303 | thisMetricPrefix = CommandMetricUtils.mungeString( 304 | thisMetricPrefix, processCommand.substring(processCommand.lastIndexOf('/') + 1)); 305 | } 306 | } 307 | } 308 | } 309 | 310 | // Second loop - get metrics 311 | for (int m = 0; m < lineColumns.length; m++) { 312 | if (lineColumns[m] == UnixMetrics.kColumnMetricPrefix || 313 | lineColumns[m] == UnixMetrics.kColumnMetricDiskName || 314 | lineColumns[m] == UnixMetrics.kColumnIgnore) { 315 | continue; 316 | } else if (lineColumns[m] == UnixMetrics.kColumnMetricName) { 317 | thisMetricName = lineMatch.group(m + 1).replaceAll("/", "-"); 318 | } else if (lineColumns[m] == UnixMetrics.kColumnMetricValue) { 319 | thisMetricValueString = lineMatch.group(m + 1); 320 | } else if (lineColumns[m] == UnixMetrics.kColumnMetricProcessName) { 321 | CommandMetricUtils.insertMetric(currentMetrics, 322 | metricDeets, CommandMetricUtils.mungeString(thisCommand, lineColumns[m]), 323 | thisMetricPrefix, "1"); 324 | } else { 325 | CommandMetricUtils.insertMetric(currentMetrics, 326 | metricDeets, CommandMetricUtils.mungeString(thisCommand, lineColumns[m]), 327 | thisMetricPrefix, lineMatch.group(m + 1)); 328 | } 329 | } 330 | 331 | // If kColumnMetricName & kColumnMetricValue were used to get metric name & value, 332 | // finally report this metric 333 | if(!thisMetricName.isEmpty() && !thisMetricValueString.isEmpty()) { 334 | CommandMetricUtils.insertMetric(currentMetrics, 335 | metricDeets, CommandMetricUtils.mungeString(thisCommand, thisMetricName), 336 | thisMetricPrefix, thisMetricValueString); 337 | } 338 | 339 | // Once we find a valid mapping for this line, 340 | // stop looking for matches for this line, 341 | // unless we explicitly want to check all regex mappings. 342 | if(!checkAllRegex) { 343 | break regexloop; 344 | } 345 | } else { 346 | logger.debug("Skipped: " + line); 347 | } 348 | } 349 | 350 | // For commands like 'top', we probably only need the first few lines. 351 | if (lineLimit > 0) { 352 | lineCount++; 353 | if (lineCount >= lineLimit) { 354 | break lineloop; 355 | } 356 | } 357 | } 358 | } 359 | 360 | public static HashMap parseSimpleMetricOutput( 361 | String thisCommand, ArrayList commandOutput) throws Exception { 362 | 363 | HashMap output = new HashMap(); 364 | for(String line : commandOutput) { 365 | line = line.trim(); 366 | if (CommandMetricUtils.singleMetricLinePattern.matcher(line).matches() 367 | && !CommandMetricUtils.dashesPattern.matcher(line).matches()) { 368 | String[] lineSplit = line.split("\\s+"); 369 | try { 370 | String metricName = Arrays.toString(Arrays.copyOfRange(lineSplit, 1, lineSplit.length)) 371 | .replaceAll("[\\[\\],]*", ""); 372 | double metricValue = Double.parseDouble(lineSplit[0]); 373 | output.put(CommandMetricUtils.mungeString(thisCommand, metricName), metricValue); 374 | } catch (NumberFormatException e) { 375 | // Means the 1st field is not a number. Value is ignored. 376 | } 377 | } 378 | } 379 | return output; 380 | } 381 | 382 | // Resets current metrics to "false" and removes stale metrics 383 | public static HashMap resetCurrentMetrics( 384 | HashMap inputMetrics) { 385 | HashMap outputMetrics = new HashMap(); 386 | for(String thisKey : inputMetrics.keySet()) { 387 | MetricOutput thisMetric = inputMetrics.get(thisKey); 388 | // If it's current, set to "false" for next iteration and transpose to output. 389 | // Reset incrementors to 'O' for next go-round 390 | if (thisMetric.isCurrent()) { 391 | thisMetric.setCurrent(false); 392 | if(thisMetric.getMetricDetail().getType().equals(MetricDetail.metricTypes.INCREMENT)) { 393 | thisMetric.resetValue(); 394 | } 395 | outputMetrics.put(thisKey, thisMetric); 396 | } 397 | } 398 | return outputMetrics; 399 | } 400 | 401 | public static String[] replaceInArray(String[] thisArray, String findThis, String replaceWithThis) { 402 | String[] outputArray = new String[thisArray.length]; 403 | for (int i=0; i < thisArray.length; i++) { 404 | outputArray[i] = thisArray[i].replaceAll(findThis, replaceWithThis); 405 | } 406 | return outputArray; 407 | } 408 | 409 | public static ArrayList replaceInArray(ArrayList thisArrayList, String findThis, String replaceWithThis) { 410 | ArrayList outputArrayList = new ArrayList(); 411 | for (int i=0; i < thisArrayList.size(); i++) { 412 | outputArrayList.add(replaceInArray(thisArrayList.get(i), findThis, replaceWithThis)); 413 | } 414 | return outputArrayList; 415 | } 416 | 417 | public static double roundNumber(double theNumber, int places) { 418 | double placesDouble = Math.pow(10, places); 419 | return Math.round(theNumber * placesDouble) / placesDouble; 420 | } 421 | } 422 | -------------------------------------------------------------------------------- /src/com/chocolatefactory/newrelic/plugins/utils/MetricDetail.java: -------------------------------------------------------------------------------- 1 | package com.chocolatefactory.newrelic.plugins.utils; 2 | 3 | public class MetricDetail { 4 | 5 | private String name, units, prefix; 6 | private int ratio; 7 | 8 | public static enum metricTypes{NORMAL, DELTA, EPOCH, INCREMENT}; 9 | private metricTypes this_type; 10 | 11 | public MetricDetail(String pname, String mname, String munits, metricTypes mtype, int mratio) { 12 | setPrefix(pname); 13 | setName(mname); 14 | setRatio(mratio); 15 | setUnits(munits); 16 | setType(mtype); 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public void setName(String name) { 24 | this.name = name; 25 | } 26 | 27 | public metricTypes getType() { 28 | return this_type; 29 | } 30 | 31 | public void setType(metricTypes mtype) { 32 | this.this_type = mtype; 33 | } 34 | 35 | public String getUnits() { 36 | return units; 37 | } 38 | 39 | public void setUnits(String units) { 40 | this.units = units; 41 | } 42 | 43 | public int getRatio() { 44 | return ratio; 45 | } 46 | 47 | public void setRatio(int ratio) { 48 | this.ratio = ratio; 49 | } 50 | 51 | public String getPrefix() { 52 | return prefix; 53 | } 54 | 55 | public void setPrefix(String prefix) { 56 | this.prefix = prefix; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/com/chocolatefactory/newrelic/plugins/utils/MetricOutput.java: -------------------------------------------------------------------------------- 1 | package com.chocolatefactory.newrelic.plugins.utils; 2 | 3 | import com.newrelic.metrics.publish.processors.EpochProcessor; 4 | 5 | public class MetricOutput { 6 | private static int kMinterval = 60; 7 | 8 | private MetricDetail mdetail; 9 | private String mname_prefix; 10 | private Number mvalue; 11 | private EpochProcessor dvalue; 12 | private boolean current; 13 | 14 | public MetricOutput(MetricDetail md, String mp, Number mv) { 15 | setNamePrefix(mp); 16 | setMetricDetail(md); 17 | // Initialize EpochCounter if this will measure a delta. 18 | // Precedes setValue such that the initial value gets set appropriately. 19 | if (this.getMetricDetail().getType().equals(MetricDetail.metricTypes.DELTA)) { 20 | dvalue = new EpochProcessor(); 21 | dvalue.process(mv); 22 | } 23 | // Initialize value to 0 if incrementor 24 | if (this.getMetricDetail().getType().equals(MetricDetail.metricTypes.INCREMENT)) { 25 | setValue(0); 26 | } 27 | setValue(mv); 28 | setCurrent(true); 29 | } 30 | 31 | public String getNamePrefix() { 32 | return mname_prefix; 33 | } 34 | 35 | public void setNamePrefix(String mp) { 36 | this.mname_prefix = mp; 37 | } 38 | 39 | public Number getValue() { 40 | return mvalue; 41 | } 42 | 43 | public void setValue(Number mv) { 44 | if (this.getMetricDetail().getRatio() > 1) { 45 | mv = mv.doubleValue() * this.getMetricDetail().getRatio(); 46 | } 47 | 48 | switch(this.getMetricDetail().getType()) { 49 | case INCREMENT: 50 | if(this.mvalue == null) { 51 | resetValue(); 52 | } 53 | this.mvalue = mv.floatValue() + this.getValue().floatValue(); 54 | break; 55 | // Converting to per-minute (per-interval) delta 56 | // EpochProcessor returns a double that is a per-second delta 57 | // (based off of the actual delta between command runs) 58 | case DELTA: 59 | try { 60 | this.mvalue = Math.round((dvalue.process(mv).doubleValue() * kMinterval)); 61 | } catch(NullPointerException e) { 62 | resetValue(); 63 | } 64 | if(this.mvalue == null) { 65 | resetValue(); 66 | } 67 | break; 68 | case NORMAL: 69 | this.mvalue = mv; 70 | break; 71 | default: 72 | this.mvalue = mv; 73 | break; 74 | } 75 | } 76 | 77 | public void resetValue() { 78 | this.mvalue = (float) 0; 79 | } 80 | 81 | public MetricDetail getMetricDetail() { 82 | return mdetail; 83 | } 84 | 85 | public void setMetricDetail(MetricDetail md) { 86 | this.mdetail = md; 87 | } 88 | 89 | public boolean isCurrent() { 90 | return current; 91 | } 92 | 93 | public void setCurrent(boolean current) { 94 | this.current = current; 95 | } 96 | } 97 | --------------------------------------------------------------------------------