No description
  • Go 97.2%
  • Makefile 2.8%
Find a file
2026-10-31 10:40:38 +01:00
config feature: add rman error checks in all log files 2026-09-30 17:49:44 +02:00
handler feature: add rman error checks in all log files 2026-09-30 17:49:44 +02:00
utils beautify code 2026-10-31 10:40:38 +01:00
.gitignore test ci 2025-11-11 09:31:22 +01:00
.gitlab-ci.yml.orig now we monitoring all our oracle export dumps, omc and ipg 2026-09-24 08:41:20 +02:00
config.json feature: add rman error checks in all log files 2026-09-30 17:49:44 +02:00
go.mod bump go version and modules 2026-10-12 07:38:30 +02:00
go.sum bump go version and modules 2026-10-12 07:38:30 +02:00
main.go feature: add rman error checks in all log files 2026-09-30 17:49:44 +02:00
Makefile test ci 2025-11-11 09:31:22 +01:00
README.md feature: add rman error checks in all log files 2026-09-30 17:49:44 +02:00

go-oracle-backup-check

Checks that Oracle expdp backup/export log files exist on a set of remote servers and reports the tail of each log to Slack. Intended to run once a day (e.g. via cron) to confirm last night's export actually ran.

How it works

For each entry in servers (see below):

  1. Compute the target date: today shifted by day_offset days.
  2. If days is set and the target date's weekday isn't in the list, skip the entry and post a SKIPPED status message to Slack.
  3. Otherwise substitute {date} (format YYYYMMDD) into path, SSH into host, and run tail -n <lines> <path>.
  4. Post the result (or the error) to Slack.
  5. If error_check is set, reuse the same target date computed in step 1 (the entry's own day_offset/days) and substitute {date} into error_check.path, then grep the matching remote file(s) for error_check.keywords (case-insensitive). Posts rman checks ok when nothing matches, or a line listing the matching filenames when something does. Skipped along with the rest of the entry when step 2 skips it, and not run if the tail check in step 3 errors.

The process exits with status 1 if any entry errored or failed to post to Slack, 0 otherwise.

Configuration (config.json)

{
  "default_user": "root",
  "default_key_path": "~/.ssh/ansible_key",
  "servers": [
    {
      "name": "D006",
      "host": "ww-az1-d006.united-it.net",
      "user": "fgau",
      "key_path": "~/.ssh/ansible_key",
      "path": "/u01/app/oracle/admin/ORDB06/expimp/{date}_*_expdp_ORDB06_full.log",
      "lines": 1,
      "day_offset": -1,
      "days": ["mon", "tue", "wed", "thu", "fri"],
      "error_check": {
        "path": "/u01/app/oracle/admin/ORDB06/rman_logs/{date}_*.log",
        "keywords": ["Error", "Fehler"]
      }
    }
  ]
}
Field Required Description
default_user no Fallback SSH user for entries that omit user.
default_key_path no Fallback SSH private key path for entries that omit key_path. ~ is expanded to the current user's home directory.
servers[].name yes Label used in logs and Slack messages.
servers[].host yes SSH host (port 22).
servers[].user no Overrides default_user.
servers[].key_path no Overrides default_key_path. ~ is expanded.
servers[].path yes Remote log path. May contain the literal token {date}, replaced with the target date as YYYYMMDD. Shell glob characters (e.g. *) are expanded by the remote shell, so they can stand in for parts of the filename that vary (timestamps, etc.).
servers[].lines no Number of trailing lines to read (tail -n). Defaults to 1.
servers[].day_offset no Number of days to add to today's date before substituting {date} (can be negative). Defaults to 0. Useful when a log for "today's" backup is actually written with yesterday's date.
servers[].days no Restricts which weekdays the log is expected to exist. Accepts short (mon, tue, wed, thu, fri, sat, sun) or long weekday names, case-insensitive. When the target date (after day_offset) falls on a day not in this list, the entry is skipped and a status message is posted to Slack instead of being checked. Omit for logs expected every day.
servers[].error_check no Adds a grep-based check for a directory of RMAN log files on the same host, using this entry's own day_offset/days to pick the target date. Omit to skip this check entirely for the host.
servers[].error_check.path yes, if error_check is set Remote path for the RMAN log(s) to grep, with the same {date} and glob-wildcard support as servers[].path.
servers[].error_check.keywords no Case-insensitive keywords to search for. Defaults to ["Error", "Fehler"].

Environment variables (.env)

Variable Required Description
SLACK_WEBHOOK_URL yes Incoming webhook URL used to post status messages.
MJ_APIKEY_PUBLIC no* Mailjet API key. Required if MJ_TO_EMAIL is set.
MJ_APIKEY_PRIVATE no* Mailjet API secret. Required if MJ_TO_EMAIL is set.
MJ_FROM_EMAIL no Sender address for status emails (must be a verified sender/domain in Mailjet). Defaults to hi@webershandwick.de.
MJ_TO_EMAIL no Recipient address for status emails, sent via the Mailjet Send API. When set, every status message is also emailed. Omit to send to Slack only.
SERVERS_CONFIG_PATH no Path to the servers config file. Defaults to config.json.

To relay status emails into a Microsoft Teams chat: point MJ_TO_EMAIL at a mailbox watched by a Power Automate flow using the "When a new email arrives" (Outlook) trigger followed by "Post message in a chat or channel" — both Standard connectors, so no Premium license or Entra ID app registration is required.

Copy .env next to the binary before running it; values are loaded via godotenv.

Build & run

make build   # builds ./build/x86_64/go-oracle-backup-check (linux/amd64, CGO disabled)
make run     # builds and runs it
make clean   # removes the built binary

Authentication

Each server is accessed over SSH using public-key authentication with the key at key_path (or default_key_path). The corresponding public key must be authorized on the target host for user.