{"id":1352,"date":"2023-07-29T12:38:19","date_gmt":"2023-07-29T17:38:19","guid":{"rendered":"https:\/\/www.nathanhunstad.com\/blog\/?p=1352"},"modified":"2023-07-29T12:38:19","modified_gmt":"2023-07-29T17:38:19","slug":"monitor-your-ups-with-logstash-the-easy-way","status":"publish","type":"post","link":"https:\/\/www.nathanhunstad.com\/blog\/2023\/07\/monitor-your-ups-with-logstash-the-easy-way\/","title":{"rendered":"Monitor your UPS with  Logstash the easy way"},"content":{"rendered":"\n<p>Many years ago, I wrote a blog post about <a href=\"https:\/\/www.nathanhunstad.com\/blog\/2015\/05\/monitoring-my-ups-with-splunk\/\" target=\"_blank\" rel=\"noopener\" title=\"\">monitoring my UPS with Splunk<\/a>. Since then, I&#8217;ve moved away from Splunk to the Elastic stack. Fortunately, moving that monitoring over was pretty much a breeze.<\/p>\n\n\n\n<p>The information is still coming from upslog, which is bundled in with nut. FIrst, I configured nut to define the UPS and the connectivity, in this case a USB connection. Then, I had to modify the <code>upslog.service<\/code> file to get it to start and monitor the correct UPS device, then output it to <code>\/var\/log\/ups.log<\/code>. Honestly, that was the hardest part of the configuration. From here, it was a breeze.<\/p>\n\n\n\n<p>Once upslog was outputting data to the log file, I simply created a logstash config to read it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>input {\n    file {\n        path =&gt; \"\/var\/log\/ups.log\"\n        tags =&gt; &#91; \"ups\" ]\n    }\n\n}<\/code><\/pre>\n\n\n\n<p>Then, this grok filter parses out all the appropriate fields:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>filter {\n  ...\n  else if \"ups\" in &#91;tags] {\n    grok {\n      match =&gt; {\n        message =&gt; &#91; \"^%{DATA:rawdate} %{DATA:rawtime} %{INT:battery.charge} %{NUMBER:battery.volts:float} %{INT:battery.load} \\&#91;%{DATA:battery.status}\\] %{GREEDYDATA}$\" ]\n      }\n      add_tag =&gt; &#91; \"ups_parsed\" ]\n    }\n    mutate {\n      copy =&gt; {\n        \"message\" =&gt; \"log.original\"\n      }\n      rename =&gt; {\n        \"host\" =&gt; \"host.hostname\"\n        \"path\" =&gt; \"file.name\"\n      }\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>This is directed into a datastream in Elastic:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>output {\n  ...\n  else if \"ups\" in &#91;tags] {\n    elasticsearch {\n      hosts =&gt; &#91; \"192.168.2.12:9200\" ]\n      index =&gt; \"logstash-ups\"\n      manage_template =&gt; false\n      user =&gt; logstash_writer\n      password =&gt; xxxxxxxxxxxxxxxx\n      action =&gt; \"create\"\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>I&#8217;m a big fan of the <a href=\"https:\/\/github.com\/elastic\/ecs\" target=\"_blank\" rel=\"noopener\" title=\"\">Elastic Common Schema<\/a> (ECS), and I&#8217;ve extended it where necessary, such as this mapping for the UPS battery fields:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\n{\n  \"_meta\": {\n    \"version\": \"1.5.0\"\n  },\n  \"date_detection\": false,\n  \"dynamic_templates\": &#91;\n    {\n      \"strings_as_keyword\": {\n        \"mapping\": {\n          \"ignore_above\": 1024,\n          \"type\": \"keyword\"\n        },\n        \"match_mapping_type\": \"string\"\n      }\n    }\n  ],\n  \"properties\": {\n    \"@timestamp\": {\n      \"type\": \"date\"\n    },\n    \"battery\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"charge\": {\n          \"type\": \"integer\"\n        },\n        \"load\": {\n          \"type\": \"integer\"\n        },\n        \"status\": {\n          \"type\": \"keyword\"\n        },\n        \"volts\": {\n          \"type\": \"float\"\n        }\n      }\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>Putting all of that together, I get parsed, well-formatted data that allows me to monitor my UPS on a custom dashboard:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.nathanhunstad.com\/blog\/wp-content\/uploads\/2023\/07\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"456\" src=\"https:\/\/www.nathanhunstad.com\/blog\/wp-content\/uploads\/2023\/07\/image-1024x456.png\" alt=\"\" class=\"wp-image-1353\" srcset=\"https:\/\/www.nathanhunstad.com\/blog\/wp-content\/uploads\/2023\/07\/image-1024x456.png 1024w, https:\/\/www.nathanhunstad.com\/blog\/wp-content\/uploads\/2023\/07\/image-300x134.png 300w, https:\/\/www.nathanhunstad.com\/blog\/wp-content\/uploads\/2023\/07\/image-768x342.png 768w, https:\/\/www.nathanhunstad.com\/blog\/wp-content\/uploads\/2023\/07\/image-1536x685.png 1536w, https:\/\/www.nathanhunstad.com\/blog\/wp-content\/uploads\/2023\/07\/image-2048x913.png 2048w, https:\/\/www.nathanhunstad.com\/blog\/wp-content\/uploads\/2023\/07\/image-1568x699.png 1568w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Many years ago, I wrote a blog post about monitoring my UPS with Splunk. Since then, I&#8217;ve moved away from Splunk to the Elastic stack. Fortunately, moving that monitoring over was pretty much a breeze. The information is still coming from upslog, which is bundled in with nut. FIrst, I configured nut to define the&hellip; <a class=\"more-link\" href=\"https:\/\/www.nathanhunstad.com\/blog\/2023\/07\/monitor-your-ups-with-logstash-the-easy-way\/\">Continue reading <span class=\"screen-reader-text\">Monitor your UPS with  Logstash the easy way<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1352","post","type-post","status-publish","format-standard","hentry","category-uncategorized","entry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/posts\/1352","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/comments?post=1352"}],"version-history":[{"count":2,"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/posts\/1352\/revisions"}],"predecessor-version":[{"id":1356,"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/posts\/1352\/revisions\/1356"}],"wp:attachment":[{"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/media?parent=1352"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/categories?post=1352"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/tags?post=1352"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}