{"id":100,"date":"2009-07-06T16:05:54","date_gmt":"2009-07-06T15:05:54","guid":{"rendered":"http:\/\/lendl.priv.at\/blog\/2009\/07\/06\/rate-limit-for-swatch\/"},"modified":"2026-01-26T12:16:13","modified_gmt":"2026-01-26T11:16:13","slug":"rate-limit-for-swatch","status":"publish","type":"post","link":"https:\/\/lendl.priv.at\/blog\/2009\/07\/06\/rate-limit-for-swatch\/","title":{"rendered":"Rate-limit for swatch"},"content":{"rendered":"<p>At work, we installed <a href=\"http:\/\/sourceforge.net\/projects\/swatch\/\">swatch<\/a> to have a look at our combined logfiles. (see <a href=\"http:\/\/articles.techrepublic.com.com\/5100-10878_11-6093879.html\">techrepublic<\/a> or <a href=\"http:\/\/linsec.ca\/Using_swatch_to_Monitor_Logfiles\">linsec<\/a> for a swatch intro.) <\/p>\n<p>But contrary to most of the examples, we&#8217;re using swatch not to check for known events, but to look out for unexpected entries. So basically our config is &#8220;ignore the known, send mail for the rest&#8221;:<\/p>\n<blockquote><p>ignore=\/&#8230;\/<br \/>\nignore=\/&#8230;\/<\/p>\n<p>watchfor=\/.\/<br \/>\nmail=&#8230;..<\/p><\/blockquote>\n<p>This has one severe drawback: every single unexpected line in a logfile will send one mail. This just doesn&#8217;t scale. <\/p>\n<p>The <strong>threshold<\/strong> feature won&#8217;t really help us, as it rejects notifications over its limit, whereas for email notifications it&#8217;s better to collect more messages into a single email. <\/p>\n<p>So I dived into the code and added a ratelimit feature for the mail Action.<\/p>\n<p>Apply the patch in  <a id=\"p101\" rel=\"attachment\"  href=\"https:\/\/lendl.priv.at\/blog\/2009\/07\/06\/rate-limit-for-swatch\/actionspmdiff\/\" title=\"Actions.pm.diff\">Actions.pm.diff<\/a> and then you can write:<\/p>\n<blockquote><p>\nwatchfor=\/.\/<br \/>\nmail=addresses=joe\\@example.com,subject=&#8221;swatch alert&#8221;,ratelimit=600,ratetag=foo<\/p><\/blockquote>\n<p>and joe will get no more than one mail per 10 mins, without missing a single message.<\/p>\n<p>As written, this config has one problem: I need to flush the messages I held back once I&#8217;m allowed to send mail again. In theory, I should have added some sort of timer-based event-handling to swatch, but I considered that to be overkill. Especially if you have multiple mail statements with different rate-limits. So I added another option to the mail Action that tells it just to flush spooled messages and do nothing more. You should trigger that option frequently, e.g. with a stanza like this at the top of your config-file:<\/p>\n<blockquote><p>\nwatchfor=\/.\/<br \/>\nmail=addresses=joe\\@example.com,subject=&#8221;swatch alert&#8221;,ratelimit=600,ratetag=foo,rateflush=1<br \/>\ncontinue<\/p>\n<p>ignore=\/   \/<br \/>\nignore=\/&#8230;\/<\/p>\n<p>watchfor=\/.\/<br \/>\nmail=addresses=joe\\@example.com,subject=&#8221;swatch alert&#8221;,ratelimit=600,ratetag=foo<\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>At work, we installed swatch to have a look at our combined logfiles. (see techrepublic or linsec for a swatch intro.) But contrary to most of the examples, we&#8217;re using swatch not to check for known events, but to look out for unexpected entries. So basically our config is &#8220;ignore the known, send mail for [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-100","post","type-post","status-publish","format-standard","hentry","category-system-administration"],"_links":{"self":[{"href":"https:\/\/lendl.priv.at\/blog\/wp-json\/wp\/v2\/posts\/100","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lendl.priv.at\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lendl.priv.at\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lendl.priv.at\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lendl.priv.at\/blog\/wp-json\/wp\/v2\/comments?post=100"}],"version-history":[{"count":1,"href":"https:\/\/lendl.priv.at\/blog\/wp-json\/wp\/v2\/posts\/100\/revisions"}],"predecessor-version":[{"id":996,"href":"https:\/\/lendl.priv.at\/blog\/wp-json\/wp\/v2\/posts\/100\/revisions\/996"}],"wp:attachment":[{"href":"https:\/\/lendl.priv.at\/blog\/wp-json\/wp\/v2\/media?parent=100"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lendl.priv.at\/blog\/wp-json\/wp\/v2\/categories?post=100"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lendl.priv.at\/blog\/wp-json\/wp\/v2\/tags?post=100"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}