{"id":34289812,"url":"https://github.com/eclecticlogic/whisper","last_synced_at":"2026-03-12T07:02:46.564Z","repository":{"id":12469576,"uuid":"15135603","full_name":"eclecticlogic/whisper","owner":"eclecticlogic","description":"Logback and Log4j v2 appender that suppresses messages of the same kind when they exceed a defined frequency and sends out a periodic digest of such suppressed messages.","archived":false,"fork":false,"pushed_at":"2022-02-18T00:45:40.000Z","size":217,"stargazers_count":31,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-12-20T13:58:46.056Z","etag":null,"topics":["digest","java","logback","slf4j","suppression"],"latest_commit_sha":null,"homepage":"http://www.eclecticlogic.com/whisper","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eclecticlogic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-12-12T12:39:07.000Z","updated_at":"2023-12-14T17:24:37.000Z","dependencies_parsed_at":"2022-09-10T22:31:08.106Z","dependency_job_id":null,"html_url":"https://github.com/eclecticlogic/whisper","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/eclecticlogic/whisper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclecticlogic%2Fwhisper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclecticlogic%2Fwhisper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclecticlogic%2Fwhisper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclecticlogic%2Fwhisper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eclecticlogic","download_url":"https://codeload.github.com/eclecticlogic/whisper/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclecticlogic%2Fwhisper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30417686,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T06:40:58.731Z","status":"ssl_error","status_checked_at":"2026-03-12T06:40:40.296Z","response_time":114,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["digest","java","logback","slf4j","suppression"],"created_at":"2025-12-17T02:02:23.061Z","updated_at":"2026-03-12T07:02:46.553Z","avatar_url":"https://github.com/eclecticlogic.png","language":"Java","readme":"# What is Whisper?\n\nHave you ever had something go wrong in your production server and had your Logback email appender immediately send you an email alert? You probably felt like a DevOps guru because you knew exactly what caused the error before anyone else. But then you realize that you've got a database issue and every user request from the app results in an error email (possibly more than one). Right at that time a backend process launches and tries to connect to the database and all hell breaks loose because your email server is now straining under the error email deluge - all 50,000 of them saying the same thing - some variation of \"could not connect to database\"!\n\nPerhaps you weren't so fortunate to see this happen in real-time. Perhaps the first time you noticed it was when you got back into work and saw the 50,000 new emails awaiting your attention. And as you sit and delete page after page of email, you have this suspicion that perhaps somewhere in those 50,000 emails (all looking alike) there is a one-off error email that may be important and you are going to accidentally delete it.\n\nWhisper is your solution to controlling error email spam. Whisper acts as a pass through appender to your default SMTP appender for emails.\nWhen the frequency of a message exceeds the configured threshold, Whisper starts to suppress it. While suppression is on, Whisper will even send you periodic digests letting you know which messages were suppressed and how many of them were suppressed. When things gets resolved and your error message frequency drops, suppression is stopped and things resume as normal. All of this happens on a per log message basis (not including the timestamp and factoring away parameters if you used the parameterized SLF4j log format).\n\n### What Logging frameworks does Whisper support?\nWhisper currently supports Logback. We hope to add support for log4j and log4jv2 in the future.\n\n### How do I get the JAR?\nWhisper is available via Maven Central repo.\n\n```\n\u003cgroupId\u003ecom.eclecticlogic\u003c/groupId\u003e\n\u003cartifactId\u003ewhisper\u003c/artifactId\u003e\n\u003cpackaging\u003ejar\u003c/packaging\u003e\n\u003cversion\u003e1.0.4\u003c/version\u003e\n```\t\n\n### How do I configure Whisper?\nYou can refer to the whisper-logback-sample.xml under src/sample/resources. Here is the gist of how to configure Whisper for use with Logback to \nhandle the most common case of suppressing ERROR messages that are sent via the email appender. \n\nTo configure the Whisper appender, first you must configure two other appenders - the regular email appender for ERROR level logs and a second\nemail appender for sending the suppression Digests when suppression is actually in effect. \n\n```\n\u003cappender name=\"errorEmail\" class=\"ch.qos.logback.classic.net.SMTPAppender\"\u003e\n\t\u003cfilter class=\"ch.qos.logback.classic.filter.LevelFilter\"\u003e\n\t\t\u003clevel\u003eERROR\u003c/level\u003e\n\t\t\u003conMatch\u003eACCEPT\u003c/onMatch\u003e\n\t\t\u003conMismatch\u003eDENY\u003c/onMismatch\u003e\n\t\u003c/filter\u003e\n\t\u003csmtpHost\u003eADDRESS-OF-YOUR-SMTP-HOST\u003c/smtpHost\u003e\n\t\u003cto\u003eEMAIL-DESTINATION\u003c/to\u003e\n\t\u003cfrom\u003eSENDER-EMAIL\u003c/from\u003e\n\t\u003csubject\u003eTESTING: %logger{20} - %m\u003c/subject\u003e\n\t\u003clayout class=\"ch.qos.logback.classic.PatternLayout\"\u003e\n\t\t\u003cpattern\u003e%date %-5level %logger{35} - %message%n\u003c/pattern\u003e\n\t\u003c/layout\u003e\n\u003c/appender\u003e\n\n\u003cappender name=\"errorDigest\" class=\"ch.qos.logback.classic.net.SMTPAppender\"\u003e\n\t\u003csmtpHost\u003eADDRESS-OF-YOUR-SMTP-HOST\u003c/smtpHost\u003e\n\t\u003cto\u003eEMAIL-DESTINATION\u003c/to\u003e\n\t\u003cfrom\u003eSENDER-EMAIL\u003c/from\u003e\n\t\u003csubject\u003e%X{whisper.digest.subject}\u003c/subject\u003e\n\t\u003clayout class=\"ch.qos.logback.classic.PatternLayout\"\u003e\n\t\t\u003cpattern\u003e%date %-5level %logger{35} - %message%n\u003c/pattern\u003e\n\t\u003c/layout\u003e\n\u003c/appender\u003e\n```\n\nNote the use of `%X{whisper.digest.subject}` for the subject of the digest appender.\n\n\nWe now configure the Whisper appender as shown below:\n\n```\n\u003cappender name=\"whisper\"\n\tclass=\"com.eclecticlogic.whisper.logback.WhisperAppender\"\u003e\n\t\u003c!-- Filter out non error logs --\u003e\n\t\u003cfilter class=\"ch.qos.logback.classic.filter.LevelFilter\"\u003e\n\t\t\u003clevel\u003eERROR\u003c/level\u003e\n\t\t\u003conMatch\u003eACCEPT\u003c/onMatch\u003e\n\t\t\u003conMismatch\u003eDENY\u003c/onMismatch\u003e\n\t\u003c/filter\u003e\n\t\u003c!-- This is the name of the logging category to use to send out error digests. This is associated with the \n\terrorDigest appender. --\u003e\n\t\u003cdigestLoggerName\u003edigest.appender.logger\u003c/digestLoggerName\u003e\n\t\u003c!--  suppressAfter specifies the criteria to enter suppression. The example below says that if 3 errors of the same kind\n\tare encountered within a 5 minute window, then suppression should kick in. --\u003e\n    \u003c!-- Other expressions: 4 in 30 seconds, 10 in 1 hour, etc. --\u003e\n\t\u003csuppressAfter\u003e3 in 5 minutes\u003c/suppressAfter\u003e\n\t\u003c!-- expireAfter specifies how much of silence the logger between messages before stopping suppression. --\u003e \n\t\u003cexpireAfter\u003e4 minutes\u003c/expireAfter\u003e\n\t\u003c!-- digestFrequency specifies how often error email digests should be sent containing statistics on messages \n\tsuppressed --\u003e\n\t\u003c!-- You can also specify the unit as sec, seconds, min, hour, hr, hrs (not beyond hours) --\u003e\n\t\u003cdigestFrequency\u003e20 minutes\u003c/digestFrequency\u003e\n\t\n\t\u003c!-- The pass-through appender for the normal case when suppression is not in-force. --\u003e\n\t\u003cappender-ref ref=\"errorEmail\" /\u003e\n\u003c/appender\u003e\n```\n\nThe digest logger name is then associated with the digestAppender and the whisper appender is included in the \nlist of default appenders:\n\n```\n\u003clogger name=\"digest.appender.logger\" level=\"error\" additivity=\"false\"\u003e\n\t\u003cappender-ref ref=\"errorDigest\" /\u003e\n\u003c/logger\u003e\n\n\u003croot level=\"debug\"\u003e\n\t\u003cappender-ref ref=\"whisper\" /\u003e\n\t\u003cappender-ref ref=\"fileAppender\" /\u003e\n\u003c/root\u003e\n```\n\n### What is the license?\nGood old [Apache License](http://apache.org/licenses/LICENSE-2.0.html).\n\n# Release Notes\n\n### v1.0.4\n\n- Fixed [bug](https://github.com/eclecticlogic/whisper/issues/6) caused when the log message itself is null.\n\n### v1.0.3\n\n- Fixed [bug](https://github.com/eclecticlogic/whisper/issues/4) that leaves Muffler in the map\n\n### v1.0.2\n\n- Fixed issue causing digest to continue to report no suppression as described [here](https://github.com/eclecticlogic/whisper/issues/3).\n\n### v1.0.1\n\n- Fixed issue (NPE on digest run) described [here](https://github.com/eclecticlogic/whisper/issues/1).\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feclecticlogic%2Fwhisper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feclecticlogic%2Fwhisper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feclecticlogic%2Fwhisper/lists"}