No description
- Go 72.3%
- JavaScript 12.9%
- Nix 11.2%
- CSS 1.6%
- HTML 1.3%
- Other 0.7%
| ci | ||
| client | ||
| cmd | ||
| .gitignore | ||
| .gitlab-ci.yml | ||
| .golangci.yml | ||
| configfile.go | ||
| COPYING | ||
| flake.nix | ||
| go.mod | ||
| go.sum | ||
| Makefile | ||
| README.txt | ||
| schema.go | ||
| schema.sql | ||
| schema.sqlite.sql | ||
| tls.go | ||
| types.go | ||
= README
nocmon is a minimal push-based monitoring solution. A central server receives
monitoring events from multiple hosts (using TLS client certificates) and
stores them in a PostgreSQL or SQLite database. Both traditional checks (e.g.
"disk full") and log messages can be sent from hosts. The list of events and the
current state is displayed in a web interface where they can be searched.
Changes can generate notifications. Checks don't have to be configured on the
server and are automatically created.
nocmon is free software and licensed under GPL version 3 or later.
== Concepts
Each event consists of a time, the check (name) (e.g. "disk", "load"), a path
to differentiate sources (which can include the host name, e.g.
"vpn/example.org"), a result (`OK`, `WARN`, `CRIT`, `MISS`) and an optional
message (for further details). If the event is a log entry, the message
contains the actual log message.
The web interface differentiates between states ("Status") and events
("Live"). The last known result of each event (which is not a log) is tracked
as state. If a state changes a notification can be generated. All events are
shown in the "Live"-view when the occur.
`MISS` is not used per default. If `DefaultMissDuration` is configured then
all states which are older than the configured time are considered stale and
transition to `MISS`. This can be used to detect dead hosts (which are
normally not visible in push-based solutions).
== Usage
Needs `go`
$ make
=== Server
Copy the server binary `nocmon` to the monitoring host. Setup a PostgreSQL
database and create the tables using `schema.sql`; SQLite databases are
initialized automatically when empty.
Create the basic configuration including server certificate. You must specify
the domain(s) where the server will be running as (for the certificate).
$ ./nocmon init config.toml example.org
Adapt `config.toml` as necessary (see below) and start the server.
$ ./nocmon serve config.toml
A basic configuration would contain the following options:
# To match client configuration below
ListenAPI = "[::]:6073"
# HTTP Web-Interface, behind reverse proxy for TLS
ListenWeb = "[::1]:9000"
# Or listen on a Unix socket
#ListenWeb = "/run/nocmon/web.sock"
# Local PostgreSQL database
DatabaseDriver = "postgres"
Database = "host=/run/postgresql database=nocmon"
# Or SQLite
#DatabaseDriver = "sqlite"
#Database = "/var/lib/nocmon/nocmon.sqlite"
=== Clients
Copy the client binary `nocmon-client`. Create the configuration for each
host. Paste the `APICert` from the server's configuration as stdin.
$ ./nocmon-client init https://example.org:6073
Append the output to the server's configuration. This permits the client to
connect to the server.
Afterwards, you can use `nocmon-client` to report monitoring events to the
server. Run `nocmon-client` without arguments to get the available
sub-commands.
== Configuration
:toml: https://toml.io/
The configuration uses {toml}[TOML]. Here a configuration file with example
values, default is empty/false for all values. All options are optional.
=== Server
....
# HTTP, can be TLS-terminated on a reverse-proxy. This can be a TCP address or
# a Unix socket path. Use "unix:path" for relative paths without a slash.
ListenWeb = "[::1]:9000"
# Unix socket permissions as octal string; empty keeps the default permissions
#ListenWebUnixSocketMode = "0660"
# Must be served directly (TLS client certificates)
ListenAPI = "[::]:6073"
# Database driver ("postgres" or "sqlite"; default "postgres")
DatabaseDriver = "postgres"
# Database connection string/path
Database = "host=/run/postgresql database=nocmon"
# slog log level
LogLevel = -4
# Created by `nocmon init`
# API certificate (PEM)
APICert = "..."
# API private key (PEM)
APIKey = "..."
# Or load the API private key from a separate file. Relative paths are
# resolved relative to this configuration file.
#APIKeyFile = "api-key.pem"
# Mark states as "MISS" after this
DefaultMissDuration = "24h"
....
==== Server: Groups
The states can be "grouped" by their path in the web interface. The same state
can be put into multiple groups. The list of groups is configured as follows.
....
[[Groups]]
Name = "example"
# Regexps of states paths to match
Paths = ["foo/.*"]
# Use "milder" color in UI when critical
Faulty = true
....
==== Server: Notifies
When a state changes a notification can be sent. This can either be an
arbitrary command, an email (sent using `sendmail -it`), or an ntfy.sh push
notification.
....
[[Notifies]]
# Regexps of event paths to notify for, empty matches all
Paths = ["foo/.*"]
# Regexp of checks to notify for, empty matches all
Checks = ["bar"]
# Also match log events
Logs = true
# Send emails
Emails = ["notify@example.org"]
# Send an ntfy.sh push notification to https://ntfy.sh/nocmon-alerts
NtfyTopic = "nocmon-alerts"
# Run commands
Cmds = [
["echo", "$NOCMON_CHECK"],
]
....
Commands receive the following environment variables:
- `NOCMON_TIME`
- `NOCMON_PATH`
- `NOCMON_CHECK`
- `NOCMON_RESULT_OLD`
- `NOCMON_RESULT_NEW`
- `NOCMON_MESSAGE`
==== Server: Clients
List of clients which are permitted to connect the server. This is the output
of `nocmon-client init`.
=== Client
Created by `nocmon-client init`, no additional configuration necessary. The
client private key can also be loaded from a separate file using `KeyFile`
instead of `Key`; relative paths are resolved relative to the configuration
file.
== License
This program is licensed under GPL version 3 or later.
Copyright (C) 2025 Simon Ruderich, with additional AI-assisted modifications
by Dominik Paulus (2026).
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.