Last active
December 18, 2022 23:24
-
-
Save rickosborne/509acbff60e3949fae80acd9a33ec597 to your computer and use it in GitHub Desktop.
Apache2 status to CloudWatch metrics shovel/export script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
----------------------------------------------------------- | |
The world's simplest Apache2-to-CloudWatch metrics shovel, | |
by Rick Osborne (rickosborne.org, github:rickosborne) | |
LICENSE: CC BY-NC-SA 4.0 | |
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 | |
https://creativecommons.org/licenses/by-nc-sa/4.0/ | |
Basically: | |
1. Enable mod_status: | |
$ a2enmod status | |
It will likely tell you it's already enabled. | |
2. If you don't already have one, add a localhost vhost: | |
/etc/apache2/sites-available/localhost.conf | |
<VirtualHost localhost:80> | |
ServerName localhost:80 | |
KeepAlive Off | |
LogLevel warn | |
CustomLog "/var/log/apache2/localhost/nossl.log" "combined" | |
ErrorLog "/var/log/apache2/localhost/nossl-err.log" | |
<Location "/server-status"> | |
SetHandler server-status | |
Require host localhost | |
</Location> | |
</VirtualHost> | |
3. Make sure that site works: | |
$ a2ensite localhost | |
4. Make sure that status page is available: | |
$ curl -v 'http://localhost/server-status?auto' | |
5. Add this script somewhere, such as: | |
/opt/cloudwatch/a2cw.js | |
Make sure you change the `aws` and `host` variables | |
if your system is weird. | |
6. Figure out where your node is installed: | |
$ which node | |
7. Run the script manually once just to be sure it's okay: | |
$ node /opt/cloudwatch/a2cw.js | |
You should see a bunch of aws commands logged. | |
8. Copy and run one of those commands to make sure your | |
awscli setup is correct. If you don't have awscli: | |
$ apt install awscli | |
Or yum or whatever. | |
9. If awscli tells you to configure the region or credentials, | |
do so now. Re-rerun one of the logged commands to test. | |
10. Add a crontab entry for 1-minute intervals: | |
$ crontab -e | |
And then a line like: | |
* * * * * /usr/bin/node /opt/cloudwatch/a2cw.js | |
11. Give it a few minutes and you should see the metrics | |
in CloudWatch. | |
12. Optionally, add more entries to the `units` map below. | |
----------------------------------------------------------- | |
*/ | |
const child = require("child_process"); | |
const http = require("http"); | |
const aws = child.execSync("which aws", {encoding: "utf-8"}).trim(); | |
const host = child.execSync("hostname", {encoding: "utf-8"}).trim(); | |
const units = { | |
"ServerUptimeSeconds": "Seconds", | |
"Load1": "Count", | |
"Load5": "Count", | |
"Load15": "Count", | |
"TotalAccesses": "Count", | |
"TotalkBytes": "Kilobytes", | |
"ReqPerSec": "Count/Second", | |
"BytesPerSec": "Bytes/Second", | |
"BytesPerReq": "Bytes", | |
"BusyWorkers": "Count", | |
"IdleWorkers": "Count", | |
"ConnsTotal": "Count", | |
"CacheUsage": "Percent", | |
}; | |
http.get({ | |
host: "localhost", | |
protocol: "http:", | |
path: "/server-status?auto", | |
method: "GET", | |
timeout: 30, | |
agent: false, | |
}, (res) => { | |
if (res.statusCode < 200 || res.statusCode >= 300) { | |
console.error("Bad status code: " + res.statusCode); | |
process.exit(0); | |
} | |
res.on("error", (e) => { | |
console.error(e); | |
process.exit(0); | |
}); | |
let data = ''; | |
res.on("data", (chunk) => { | |
data += chunk; | |
}); | |
res.on("end", () => { | |
const lines = data.split("\n"); | |
for (const line of lines) { | |
const match = line.match(/^([^:]+):\s+(\d+(\.\d+)?)%?$/); | |
if (match) { | |
const key = (match[1] || '').replace(/\s+/g, ""); | |
const value = parseFloat(match[2]); | |
const unit = units[key]; | |
if (unit != null) { | |
const command = `${aws} cloudwatch put-metric-data --metric-name 'httpd-${key}' --unit '${unit}' --value ${value} --dimensions 'host=${host}' --namespace 'HTTP:Apache'`; | |
console.log(command); | |
child.execSync(command); | |
} | |
} | |
} | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment