{"id":36790514,"url":"https://github.com/csmith/goplum","last_synced_at":"2026-01-12T13:25:11.971Z","repository":{"id":38334197,"uuid":"296113346","full_name":"csmith/goplum","owner":"csmith","description":"Plugin-based monitoring and alerting system, written in Go","archived":false,"fork":false,"pushed_at":"2025-11-26T12:28:01.000Z","size":654,"stargazers_count":5,"open_issues_count":18,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-11-29T10:37:45.235Z","etag":null,"topics":["alerting","golang","monitoring"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/csmith.png","metadata":{"files":{"readme":"README.adoc","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-09-16T18:19:25.000Z","updated_at":"2025-11-26T12:28:00.000Z","dependencies_parsed_at":"2023-02-14T21:46:09.245Z","dependency_job_id":"76a20359-8c66-4ca1-8ea4-c97ccedeeb33","html_url":"https://github.com/csmith/goplum","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/csmith/goplum","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csmith%2Fgoplum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csmith%2Fgoplum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csmith%2Fgoplum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csmith%2Fgoplum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/csmith","download_url":"https://codeload.github.com/csmith/goplum/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csmith%2Fgoplum/sbom","scorecard":{"id":311059,"data":{"date":"2025-08-11","repo":{"name":"github.com/csmith/goplum","commit":"04ea6f05475b587f56093caed2338a7a57189a4f"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.2,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/5 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/image.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":7,"reason":"9 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENCE:0","Info: FSF or OSI recognized license: MIT License: LICENCE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 25 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":2,"reason":"dependency not pinned by hash detected -- score normalized to 2","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/image.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/csmith/goplum/image.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/csmith/goplum/test.yml/master?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:3","Warn: containerImage not pinned by hash: Dockerfile:18: pin your Docker image by updating ghcr.io/greboid/dockerbase/nonroot:1.20250803.0 to ghcr.io/greboid/dockerbase/nonroot:1.20250803.0@sha256:4771328537af0c3e3f4aac642d419e454b074e7f514e9f3a66fc704b56ba4f08","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   2 containerImage dependencies pinned","Info:   1 out of   1 goCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}}]},"last_synced_at":"2025-08-17T23:11:13.363Z","repository_id":38334197,"created_at":"2025-08-17T23:11:13.363Z","updated_at":"2025-08-17T23:11:13.363Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28338997,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T12:22:26.515Z","status":"ssl_error","status_checked_at":"2026-01-12T12:22:10.856Z","response_time":98,"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":["alerting","golang","monitoring"],"created_at":"2026-01-12T13:25:11.892Z","updated_at":"2026-01-12T13:25:11.960Z","avatar_url":"https://github.com/csmith.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":":toc:\n:toc-placement!:\n\nimage::.images/banner.png?raw=true[Goplum]\n\nGoplum is an extensible monitoring and alerting daemon designed for\npersonal infrastructure and small businesses. It can monitor\nwebsites and APIs, and send alerts by a variety of means if they go down.\n\ntoc::[]\n\n== Features\n\n**Highly extensible**: Goplum supports plugins written in Go\nto define new monitoring rules and alert types, and it has an API\nfor integration with other services and tools.\n\n**Get alerts anywhere**: Goplum supports a variety of ways to\nalert you out-of-the-box:\n\n[width=\"100%\",cols=\"3\",frame=\"none\",grid=\"none\"]\n|=====\n| image:.images/alerts/discord.png[Discord logo] Discord\n| image:.images/alerts/mail.png[Mail icon] E-mail\n| image:.images/alerts/msteams.png[Microsoft Teams icon] Microsoft Teams\n| image:.images/alerts/phone.png[Phone icon] Phone call (via Twilio)\n| image:.images/alerts/pushover.png[Pushover logo] Pushover\n| image:.images/alerts/slack.png[Slack logo] Slack\n| image:.images/alerts/sms.png[SMS icon] SMS (via Twilio)\n| image:.images/alerts/webhook.png[Webhook logo] Webhook\n|\n|=====\n\n**Lightweight**: Goplum has a small resource footprint, and all\nchecks are purpose-written in Go. No need to worry about chains\nof interdependent scripts being executed.\n\n**Heartbeat monitoring**: Have an offline service or a cron job\nthat you want to monitor? Have it send a heartbeat to Goplum\nperiodically and get alerted if it stops.\n\n**Simple to get started**: If you're set up to run services in\ncontainers, you can get Goplum up and running in a couple of minutes.\n\n**Alert storm prevention**: Group related checks together and set\nlimits on how many alerts can be sent from a group within a time\nwindow, preventing notification overload when multiple services fail.\n\n== Getting started\n\n=== Basic configuration\n\nGoplum works by running a number of _checks_ (which test to see\nif a service is working or not), and when they change state running\nan _alert_ that notifies you about the problem.\n\nChecks and alerts are both defined in Goplum's config file. A\nminimal example looks like this:\n\n[source]\n----\ncheck http.get \"example.com\" { \u003c1\u003e\n  url = \"https://example.com/\" \u003c2\u003e\n}\n\nalert twilio.sms \"Text Bob\" { \u003c3\u003e\n  sid = \"sid\"\n  token = \"token\"\n  from = \"+01 867 5309\"\n  to = \"+01 867 5309\" \u003c4\u003e\n}\n----\n\u003c1\u003e Goplum's configuration consists of \"blocks\". The contents\n    of the blocks are placed within braces (`{}`). This is\n    a \"check block\"; these will likely make up the bulk of your\n    configuration.\n    * `http.get` is the type of check we want to execute. The\n      `http` part indicates it comes from the HTTP plugin, while\n      the `get` part is the type of check.\n    * All checks (and alerts) have a unique name, in this case\n      we've called it \"example.com\". If a check starts to fail,\n      the alert you receive will contain the check name.\n\u003c2\u003e Parameters for the check are specified as `key = value`\n    pairs within the body of the check. The documentation for\n    each check and alert will explain what parameters are available,\n    and whether they're required or not.\n\u003c3\u003e Like checks, alerts have both a type and a name. Here we're\n    using the `sms` alert from the `twilio` plugin, and we've\n    named it `Text Bob`.\n\u003c4\u003e The `twilio.sms` alert has a number of required parameters\n    that define the account you wish to use and the phone numbers\n    involved. These are all just given as `key = value` pairs.\n\nThis simple example will try to retrieve \\https://example.com/\nevery thirty seconds. If it fails three times in a row, a text\nmessage will be sent using Twilio. Then if it consistently starts\npassing again another message will be sent saying it has recovered.\nDon't worry - these numbers are all configurable: see the\n\u003c\u003cDefault Settings\u003e\u003e section.\n\nIn this example we used the `http.get` check and the `twilio.sms`\nalert. See the \u003c\u003cAvailable checks and alerts\u003e\u003e section for details\nof the other types available by default.\n\nThere is a complete link:docs/syntax.adoc[syntax guide] available\nin the `docs` folder if you need to look up a specific aspect of\nthe configuration syntax.\n\n=== Docker\n\nThe easiest way to run Goplum is using Docker. Goplum doesn't require\nany privileges, settings, or ports exposed to get a basic setup\nrunning. It just needs the configuration file, and optionally a\npersistent file it can use to persist data across restarts:\n\nRunning it via the command line:\n\n[source, shell script]\n----\n# Create a configuration file\nvi goplum.config\n\n# Make a 'tombstone' file that Goplum's unprivileged user can write\ntouch goplum.tomb\nchown 65532:65532 goplum.tomb\n\n# Start goplum\ndocker run -d --restart always \\\n   -v $(PWD)/goplum.conf:/goplum.conf:ro \\\n   -v $(PWD)/goplum.tomb:/tmp/goplum.tomb \\\n   ghcr.io/csmith/goplum\n----\n\nOr using Docker Compose:\n\n[source,yaml]\n----\nversion: \"3.8\"\n\nservices:\n  goplum:\n    image: ghcr.io/csmith/goplum\n    volumes:\n      - ./goplum.conf:/goplum.conf\n      - ./goplum.tomb:/tmp/goplum.tomb\n    restart: always\n----\n\nThe `latest` tag points to the latest stable release of Goplum, if\nyou wish to run the very latest build from this repository you can\nuse the `dev` tag.\n\n=== Without Docker\n\nWhile Docker is the easiest way to run Goplum, it's not that hard to run it\ndirectly on a host without containerisation. See the\nlink:docs/baremetal.adoc[installing without Docker] guide for more information.\n\n== Usage\n\n=== Available checks and alerts\n\nAll checks and alerts in Goplum are implemented as plugins. The following are maintained in\nthis repository and are available by default in the Docker image. Each plugin has its own\ndocumentation, that explains how its checks and alerts need to be configured.\n\n|====\n| Plugin | checks | alerts\n\n| link:plugins/discord[discord]\n| -\n| message\n\n| link:plugins/http[http]\n| get, healthcheck\n| webhook\n\n| link:plugins/network[network]\n| connect, portscan\n| -\n\n| link:plugins/heartbeat[heartbeat]\n| received\n| -\n\n| link:plugins/msteams[msteams]\n| -\n| message\n\n| link:plugins/pushover[pushover]\n| -\n| message\n\n| link:plugins/slack[slack]\n| -\n| message\n\n| link:plugins/smtp[smtp]\n| -\n| send\n\n| link:plugins/snmp[snmp]\n| int, string\n| -\n\n| link:plugins/twilio[twilio]\n| -\n| call, sms\n\n| link:plugins/debug[debug]\n| random\n| sysout\n\n| link:plugins/exec[exec]\n| command\n| -\n|====\n\nThe `docs` folder contains link:docs/example.conf[an example configuration file]\nthat contains an example of every check and alert fully configured.\n\n=== Settling and thresholds\n\nWhen Goplum first starts, it is not aware of the current state of your services.\nTo avoid immediately sending alerts when the state is determined, Goplum waits for\neach check to **settle** into a state, and then only alerts when that state\nsubsequently changes.\n\nGoplum uses **thresholds** to decide how many times a check result must happen in\na row before it's considered settled. By default, this the threshold is two \"good\"\nresults or two \"failing\" results, but this can be changed - see \u003c\u003cDefault Settings\u003e\u003e.\n\nFor example:\n\n----\n Goplum                    Failing            Recovery\n starts                     Alert               Alert\n   ↓                          ↓                   ↓\n    ✓ ✓ ✓ ✓ ✓ ✓ ✓ 🗙 ✓ ✓ ✓ 🗙 🗙 🗙 🗙 🗙 ✓ 🗙 ✓ 🗙 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ …\n       ↑                      ↑                   ↑\n  State settles          State becomes       State becomes\n    as \"good\"              \"failing\"            \"good\"\n----\n\n=== Default Settings\n\nAll checks have a number of additional settings to control how they work. These can be\nspecified for each check, or changed globally by putting them in the \"defaults\" section.\nIf they're not specified then Goplum's built-in defaults will be used.\n\n|===\n|Setting |Description |Default\n\n|`interval`\n|Length of time between each run of the check.\n|`30s`\n\n|`timeout`\n|Maximum length of time the check can run for before it's terminated.\n|`20s`\n\n|`alerts`\n|A list of alert names to trigger when the service changes state.\n Supports '*' as a wildcard.\n|`[\"*\"]`\n\n|`groups`\n|A list of group names this check belongs to.\n|`[]`\n\n|`failing_threshold`\n|The number of checks that must fail in a row before a failure alert is raised.\n|`2`\n\n|`good_threshold`\n|The number of checks that must pass in a row before a recovery alert is raised.\n|`2`\n|===\n\nFor example, to change the `interval` and `timeout` for all checks:\n\n[source,goplum]\n----\ndefaults {\n  interval = 2m\n  timeout = 30s\n}\n----\n\nOr to specify a custom timeout and alerts for one check:\n\n[source,goplum]\n----\ncheck http.get \"get\" {\n  url = \"https://www.example.com/\"\n  timeout = 60s\n  alerts = [\"Text Bob\"]\n}\n----\n\n=== Groups and Alert Storm Prevention\n\nWhen multiple services fail simultaneously (e.g., when a server goes down), \nyou might receive dozens of alerts at once. Groups help prevent this alert \nstorm by limiting how many alerts can be sent within a time window.\n\nTo create a group:\n\n[source,goplum]\n----\ngroup \"webservices\" {\n  alert_limit = 3           # Maximum 3 alerts from this group\n  alert_window = 10m        # Within a 10 minute window\n  \n  defaults {\n    interval = 30s          # Default settings for checks in this group\n    timeout = 10s\n  }\n}\n----\n\nThen add checks to the group:\n\n[source,goplum]\n----\ncheck http.get \"website\" {\n  url = \"https://example.com/\"\n  groups = [\"webservices\"]\n}\n\n# ... other checks ...\n\ncheck http.get \"api\" {\n  url = \"https://api.example.com/\"\n  groups = [\"webservices\"]\n}\n----\n\nWith this configuration, if all the websites fail when their server crashes,\nyou'll receive at most 3 alerts in any 10-minute period.\n\nChecks can belong to multiple groups, and groups can have their own default\nsettings that override the global defaults but can be overridden by individual\ncheck settings.\n\n== Advanced topics\n\n=== Creating new plugins\n\nGoplum is designed to be easily extensible. Plugins must have a main package which contains\na function named \"Plum\" that returns an implementation of `goplum.Plugin`. They are then\ncompiled with the `-buildtype=plugin` flag to create a shared library.\n\nThe Docker image loads plugins recursively from the `/plugins` directory, allowing you to\nmount custom folders if you wish to supply your own plugins.\n\nNote that the Go plugin loader does not work on Windows. For Windows-based development,\nthe `goplumdev` command hardcodes plugins, skipping the loader.\n\n=== gRPC API\n\nIn addition to allowing plugins to define new checks and alerts, GoPlum provides a gRPC\nAPI to enable development of custom tooling and facilitate use cases not supported by\nGoPlum itself (e.g. persisting check history indefinitely). The API is currently in\ndevelopment; more information can be found in the link:docs/api.adoc[API documentation].\n\n=== plumctl command-line tool\n\nGoplum comes with `plumctl`, a command-line interface to inspect the state of Goplum\nas well as perform certain operations such as pausing and resuming a check. `plumctl`\nuses the \u003c\u003cgRPC API\u003e\u003e. For more information see the\nlink:docs/plumctl.adoc[plumctl documentation].\n\n== Licence and credits\n\nGoplum is licensed under the MIT licence. A full copy of the licence is available in\nthe link:LICENCE[LICENCE] file.\n\nSome icons in this README are modifications of the Material Design icons created by Google\nand released under the https://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0 licence].\n\nGoplum makes use of a number of third-party libraries. See the link:go.mod[go.mod] file\nfor a list of direct dependencies. Users of the docker image will find a copy of the\nrelevant licence and notice files under the `/notices` directory in the image.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsmith%2Fgoplum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcsmith%2Fgoplum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsmith%2Fgoplum/lists"}