Email notifications about warnings in the admin log

I don’t really regularly look at my Nextcloud server, so when I do, there are often a number of warnings, many of which have repeated themselves a lot.

Isn’t there a way to set up an email notification system about these warnings?

we don’t look at your server much either and we’re no good at guessing :rofl:

you forgot Support template. Please use this when you request support without that information none of us will be able to assist.

I understand that that template is very useful for a specific problem.

But I just want to know whether it’s possible to configure email notifications about warnings in the logs.

I can’t imagine how anyone could think that template thing is relevant…

I don’t know of any built-in feature that can do that. But if you want to build your own solution: The logs are stored in file in the data directory ($datadirectory/nextcloud.log). You could set something up using a Bash script (or something similar), a cron job, etc.

In the worst case your mailbox can be flooded with hundrets of warning-emails per minute(!!!), if there is a configuration error or an update of an app creates errors due to a bug.

So it is better to view frequently into the nextcloud.log.

I was thinking more in the lines of a daily (or other cron based) check, and if in the last x amount of time new warnings/errors have occurred: send an email.

This is not possible out of the box, and I couldn’t find a Nextcloud app to do this with a quick search either.

You could open a feature request on GitHub or build something yourself, such as a Bash script that you could run regularly via Cron or Systemd. Alternatively, and probably overall a nicer solution, would be using an external log aggregation software with that functionality.

That sounds interesting (while useful for other services). Do you have a suggestion?

For me, this topic is a great remark. As for a lot of us, the administration of our Nextcloud infrastructure is not our daily job, something warning us on urgent action to be taken could save from a major failure. For instance, I’m looking how I could get an Email from the “notification system” at the end of a Backup batch. Why should I need to install another mail app if there is already a notification system who can do it for (and better than) me. Maybe something like an external command (API?) could do the job? And I would get an Email with the beautiful Nextcloud logo on it…

This is one of the very simplest tasks imaginable, and all the necessary tools are already built-in:

A small script that runs via cron:

‘/usr/local/bin/nc-log-notifications.sh’

#!/usr/bin/env bash
#
# @license MIT
# @copyright 2026 [ernolf] Raphael Gradenwitz

# Edit to your needs:
OCC="sudo -u www-data php -f /var/www/nextcloud/occ"
ADMIN="admin"
LOGFILE="/var/log/nextcloud/nextcloud.log"
STATEFILE="/var/lib/nc-log-monitor/last_position"

mkdir -p "$(dirname "$STATEFILE")"

# Read new entries since last run
LAST_POS=$(cat "$STATEFILE" 2>/dev/null || echo 0)
CURRENT_SIZE=$(wc -c < "$LOGFILE")

if [ "$CURRENT_SIZE" -eq "$LAST_POS" ]; then
    exit 0
elif [ "$CURRENT_SIZE" -lt "$LAST_POS" ]; then
    echo 0 > "$STATEFILE"
    exit 0
fi

WARNINGS=$(tail -c +"$LAST_POS" "$LOGFILE" | grep -c '"level":2\|"level":3\|"level":4')

if [ "$WARNINGS" -gt 0 ]; then
    $OCC notification:generate $ADMIN \
        "$WARNINGS new warnings/errors in the log" \
        -l "Check the admin log for details"
fi

echo "$CURRENT_SIZE" > "$STATEFILE"
  • Run it twice by hand to see if it works - the first run will scan the existing log and send a notification, the second run should produce no output (confirming the position was saved correctly) - then add a cron job to /etc/crontab file, to run it either
    • every 15 minutes:
    */15	*	*	*	*	root	/usr/local/bin/nc-log-notifications.sh
    
    • every 30 minutes
    */30	*	*	*	*	root	/usr/local/bin/nc-log-notifications.sh
    
    • or every hour ‘0’:
    0	*	*	*	*	root	/usr/local/bin/nc-log-notifications.sh
    


  • You can run it as your webserver user (e.g. www-data) as well:
    */15	*	*	*	*	www-data	/usr/local/bin/nc-log-notifications.sh
    
    but then you have to first change this:
    OCC="sudo -u www-data php -f /var/www/nextcloud/occ"
    
    to this:
    OCC="php -f /var/www/nextcloud/occ"
    
    AND create the state dir, because www-data can not write to /var/lib:
    sudo mkdir -p /var/lib/nc-log-monitor && sudo chown www-data: /var/lib/nc-log-monitor
    


Now you will receive notifications about warnings in the logfile.

You can configure your notifications to send you an email if you don’t react to them:

h.t.h.


ernolf

Where to change this?

In the script:

So, I played around with ChatGPT a bit and “vibe-scripted” something that I’d like to share here…

The main difference between this script and @ernolf’s is that it doesn’t use Nextcloud’s notification system.

Advantages:

  • It sends dedicated emails regarding new log entries—and only those, not mixed in with any other notifications in Nextcloud that may have occurred in the last hour.
  • It includes the content of the log messages in the email body

Disadvantages:

  • No Nextcloud logo in the email :wink:
  • It requires a functioning local email relay, e.g., Postfix, Exim, msmtp, etc.

I briefly tested the script on a test server, and it seems to work, but I haven’t done any extensive testing, and I’m not a scripting expert like @ernolf, so YMMV:

#!/usr/bin/env bash

set -euo pipefail

# =========================================================
# Nextcloud Log Email Monitor
# =========================================================

LOGFILE="/var/log/nextcloud/nextcloud.log"

STATE_DIR="/var/tmp/nextcloud-log-monitor"
OFFSET_FILE="${STATE_DIR}/offset"
INODE_FILE="${STATE_DIR}/inode"

MAIL_TO="root"

HOSTNAME="$(hostname)"


# =========================================================
# Create state directory
# =========================================================

mkdir -p "$STATE_DIR"

# =========================================================
# Initialize state
# =========================================================

[[ -f "$OFFSET_FILE" ]] || echo 0 > "$OFFSET_FILE"
[[ -f "$INODE_FILE" ]] || echo 0 > "$INODE_FILE"

LAST_OFFSET=$(cat "$OFFSET_FILE")
LAST_INODE=$(cat "$INODE_FILE")

CURRENT_INODE=$(stat -c %i "$LOGFILE")

# =========================================================
# Detect log rotation
# =========================================================

if [[ "$CURRENT_INODE" != "$LAST_INODE" ]]; then
    LAST_OFFSET=0
fi

# =========================================================
# Read only new content
# =========================================================

LOG_SIZE=$(stat -c %s "$LOGFILE")

# If log got truncated
if (( LAST_OFFSET > LOG_SIZE )); then
    LAST_OFFSET=0
fi

NEW_CONTENT=$(tail -c +"$((LAST_OFFSET + 1))" "$LOGFILE")

# Save current state immediately
echo "$LOG_SIZE" > "$OFFSET_FILE"
echo "$CURRENT_INODE" > "$INODE_FILE"

# =========================================================
# Filter levels 2/3/4
# =========================================================

MATCHES=$(echo "$NEW_CONTENT" | jq -c '
    select(.level == 2 or .level == 3 or .level == 4)
' 2>/dev/null || true)

if [[ -z "$MATCHES" ]]; then
    exit 0
fi

# =========================================================
# Format readable output
# =========================================================

FORMATTED=$(echo "$MATCHES" | jq -r '
    "Time:    \(.time)\n" +
    "Level:   \(.level)\n" +
    "App:     \(.app)\n" +
    "Message: \(.message)\n" +
    "User:    \(.user // "-")\n" +
    "--------------------------------------------------"
')

# =========================================================
# Send email
# =========================================================

EMAIL_BODY=$(cat <<EOF
New warnings/errors detected in Nextcloud log on ${HOSTNAME}

==================================================

${FORMATTED}

==================================================

Log file:
${LOGFILE}
EOF
)

echo "$EMAIL_BODY" | mail -s "New warnings/errors detected in Nextcloud log on $(hostname)" "$MAIL_TO"

The output added to the email body looks like this:

New warnings/errors detected in Nextcloud log on testcloud

==================================================

--------------------------------------------------
Time:    2026-05-09T10:08:30+02:00
Level:   2
App:     no app in context
Message: Login failed: admin (Remote IP: XXX.XXX.XXX.XXX)
User:    --
-------------------- ------------------------------
Time:    2026-05-09T10:08:33+02:00
Level:   2
App:     no app in context
Message: Login failed: admin (Remote IP: XXX:XXX:XXX.XXX)
User:    --
--------------------------------------------------

==================================================

Log file:
/var/log/nextcloud/nextcloud.log

Small note: If the log file rotated during the last email/notification and the new one, new log entries that are still in the old log file will not be reported

Yeah, you’re right, of course. And when I have some time and motivation, I might try to come up with a solution for that.

That said, for a small home instance, it’s not necessarily a huge issue. Most of the errors you may actually need to tackle will usually reappear in the logs anyway, and that one-time error or warning that just happend to occur in the short time window between log rotation and the last cron job, and therefore gets missed, is probably negligible.

Just to be clear: This is in no way intended to replace proper monitoring or log aggregation and SIEM solutions in a business-critical environment. :wink:

Hi @bb77, hi @zomtec2311,

Using an LLM to generate code is fine, but you should be the one in charge of the design – the LLM should only be the tool to generate the code

I would find it extremely problematic to send log outputs wrapped in transparent film (e-mail) over the Internet! For this reason, I have only limited the notification in my solution to the amount of warnings. The user should then view the log entries via the existing and secure channels.

If you’re doing logrotating and absolutely do not want to miss a log entry, you should use the system’s logrotator and then ad a prerotate script to the “/etc/logrotate.d/nextcloud” file:

/var/log/nextcloud/*.log {
    rotate 2
    su www-data www-data
    size 10485760
    missingok
    prerotate
        [ -x "/usr/local/bin/nc-upgrade-notifications.sh" ] && "/usr/local/bin/nc-upgrade-notifications.sh" || true
    enscript
    create 640 www-data www-data
    compress
    delaycompress
}

(Just as an example, change it to your needs)


ernolf

Actually, I explicitly told the LLM to do this.

But yes, you’re right of course. Sending log messages via email over the internet probably isn’t a good idea. That said, if you have your own mail server either locally or if the connection is encrypted, that shoud mitigate the risk of them leaking somewhat. But even then, perhaps the messages don’t necessarily shouldn’t be on that mail server, given any compliance rules in companies, etc.

So, yeah, it’s definitely something to consider, and you might be better off leaving that part out. :wink: