{"id":1137,"date":"2017-01-22T20:43:01","date_gmt":"2017-01-23T04:43:01","guid":{"rendered":"https:\/\/partofthething.com\/thoughts\/?p=1137"},"modified":"2017-01-22T20:52:06","modified_gmt":"2017-01-23T04:52:06","slug":"getting-live-alerts-when-your-website-is-visited-with-apache-mqtt-and-home-assistant","status":"publish","type":"post","link":"https:\/\/partofthething.com\/thoughts\/getting-live-alerts-when-your-website-is-visited-with-apache-mqtt-and-home-assistant\/","title":{"rendered":"Getting live alerts when your website is visited with Apache, MQTT, and home-assistant"},"content":{"rendered":"<p>I have a website or two and sometime wish I could get notifications whenever someone visited them, just for fun. Well I did it, and now I can get beeps in my home whenever anyone visits. It&#8217;s kind of cool to hear it go off, though normally it will be annoying, so we need a switch for it.<\/p>\n<p><a href=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/2017\/01\/Screenshot-from-2017-01-22-20-37-04.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1139\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/2017\/01\/Screenshot-from-2017-01-22-20-37-04.png\" alt=\"\" width=\"395\" height=\"56\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/2017\/01\/Screenshot-from-2017-01-22-20-37-04.png 395w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/2017\/01\/Screenshot-from-2017-01-22-20-37-04-300x43.png 300w\" sizes=\"auto, (max-width: 395px) 100vw, 395px\" \/><\/a><!--more--><\/p>\n<p>Inventory: I already have set up an apache2 web server with my webpage on it, an <a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-install-and-secure-the-mosquitto-mqtt-messaging-broker-on-ubuntu-16-04\">MQTT broker<\/a>, and a <a href=\"https:\/\/home-assistant.io\">home-assistant <\/a>based <a href=\"https:\/\/partofthething.com\/thoughts\/?cat=75\">home-automation setup, hooked up to my stereo, lights, and other things<\/a>. (I&#8217;m going to skip the installation of all that for this post.)<\/p>\n<p>We all know you can live monitor your apache log with:<\/p>\n<p><code>tail -f \/var\/log\/apache2\/access.log<\/code><\/p>\n<p>Turns out, Apache supports <a href=\"https:\/\/httpd.apache.org\/docs\/2.4\/logs.html#piped\">Piped Logs<\/a> which allow you to send your log data to anything. Let&#8217;s pipe the Apache log output to a Python script that can trigger events, while at the same time maintaining the regular old text apache log. In your sites-enabled apache config file, change the log line to this:<\/p>\n<pre class=\"toolbar:2 lang:default highlight:0 decode:true\" title=\"site apache2 configuration line for logs\">CustomLog \"|$\/usr\/bin\/tee -a ${APACHE_LOG_DIR}\/access.website.log | \/usr\/local\/bin\/apacheLogAlert.py\" combined<\/pre>\n<p>The script just has to monitor for regular expressions and publish to the MQTT broker when they&#8217;re found. I limited it to off-root html files for now, but will tune accordingly.<\/p>\n<pre class=\"lang:python decode:true \" title=\"Apache \/ MQTT alert system\">#!\/usr\/bin\/python3\r\n\"\"\"\r\nReceive Apache log information and perform actions based on it. \r\n\r\nSet up using an apache2 piped log with tee:\r\n\r\n\"\"\"\r\nMOSQUITTO_LINE = 'mosquitto_pub -h myserver.com -p MYPORT -t {} -m \"ON\" -u USER -P PASSWORD --capath \/etc\/ssl\/certs'\r\n\r\nTOPIC = 'webserver\/servername\/hit'\r\n\r\nimport sys\r\nimport re\r\nimport subprocess\r\nimport time\r\nimport logging\r\nimport logging.handlers\r\n\r\nLOG = logging.getLogger('ApacheMonitor')\r\nLOG.setLevel(logging.DEBUG)\r\nhandler = logging.handlers.SysLogHandler(address = '\/dev\/log')\r\nLOG.addHandler(handler)\r\n\r\nPATTERNS = [r'GET \/\\S*html',\r\n#            '\"GET \/ HTTP\/1.1\" 200'\r\n           ]\r\n\r\ndef monitor():\r\n    \r\n    while True:\r\n        time.sleep(1)\r\n        for line in sys.stdin:\r\n            #LOG.debug('Monitoring: {}\\n'.format(line))\r\n            for pat in PATTERNS:\r\n                if re.search(pat, line):\r\n                    trigger()\r\n    \r\n\r\ndef trigger():\r\n    \"\"\"\r\n    Send MQTT message that there has been a hit.\r\n\r\n    It should be reset by the receiver.\r\n    \"\"\"\r\n    subprocess.call(MOSQUITTO_LINE.format(TOPIC), shell=True)\r\n        \r\n\r\nif __name__ == '__main__':\r\n    LOG.debug('Beginning log monitor.')\r\n    try:\r\n        monitor()\r\n    finally:\r\n        LOG.debug('Closing log monitor.')\r\n<\/pre>\n<p>Note the main loop with sleeping was adapted from <a href=\"http:\/\/stackoverflow.com\/questions\/7056306\/python-wait-until-data-is-in-sys-stdin\">this SO post.<\/a> You will only get a max of 1 alert per second.<\/p>\n<p>Then you just have some simple configuring to do in home-assistant. Here&#8217;s my the relevant config. You just setup a MQTT client and a binary sensor based on the MQTT signal that gets flipped on by the above script. Then you make an automation that detects it flipping on, plays a sound and flips it back off, waiting for the next signal from the script. It&#8217;s awesome! You could alternatively make a sensor that measures the hit rate and turns a light redder when you are having more traffic, or anything! The possibilities are endless. With home-assistant you an also set up email alerts, SMS, etc. for other kinds of conditions, so this actually makes a really neat, if not convoluted, log monitoring setup. You can also turn the alert automation on and off with a GUI toggle on the frontend.<\/p>\n<pre class=\"lang:yaml decode:true\" title=\"home assistant config for MQTT alerts\">mqtt:\r\n  broker: !secret remote_server\r\n  port: !secret mqtt_port\r\n  client_id: home-assistant\r\n  keepalive: 60\r\n  username: !secret user\r\n  password: !secret mqtt_pass\r\n  certificate: \/etc\/ssl\/certs\/DST_Root_CA_X3.pem\r\n  protocol: 3.1\r\n  birth_message:\r\n    topic: 'home\/status\/hass'\r\n    payload: 'online'\r\n    qos: 1\r\n    retain: true\r\n\r\nbinary_sensor:\r\n  - platform: mqtt\r\n    name: \"Webpage Hit\"\r\n    state_topic: \"webserver\/webpage\/hit\"\r\n\r\nshell_command:\r\n  beep: mpg321 -g 50 \/opt\/sounds\/beep.mp3\r\n  reset_web_alert: mosquitto_pub -h server.com -p PORT -t webserver\/webpage\/hit -m \"OFF\" -u USER -P PASSWORD --capath \/etc\/ssl\/certs\r\n\r\nautomation:\r\n - alias: Web traffic ding\r\n   trigger:\r\n     platform: state\r\n     entity_id: binary_sensor.webpage_hit\r\n     to: 'on'\r\n     from: 'off'\r\n   action:\r\n     - service: shell_command.beep\r\n     - service: shell_command.reset_web_alert\r\n<\/pre>\n<p>You may want another one that calls <code>reset_web_alert<\/code> if it&#8217;s on for 1 minutes in case you reboot home-assistant and the MQTT topic is left in the ON position.<\/p>\n<p><em>Filed to: Narcissism<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have a website or two and sometime wish I could get notifications whenever someone visited them, just for fun. Well I did it, and now I can get beeps in my home whenever anyone visits. It&#8217;s kind of cool to hear it go off, though normally it will be annoying, so we need a &hellip; <a href=\"https:\/\/partofthething.com\/thoughts\/getting-live-alerts-when-your-website-is-visited-with-apache-mqtt-and-home-assistant\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Getting live alerts when your website is visited with Apache, MQTT, and home-assistant<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[3,75],"tags":[],"class_list":["post-1137","post","type-post","status-publish","format-standard","hentry","category-computers","category-home-automation"],"_links":{"self":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/1137","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/comments?post=1137"}],"version-history":[{"count":6,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/1137\/revisions"}],"predecessor-version":[{"id":1144,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/1137\/revisions\/1144"}],"wp:attachment":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/media?parent=1137"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/categories?post=1137"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/tags?post=1137"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}