# Recommended LogQL alert rules for docker-fclones-scheduler, for Loki's ruler. # Thresholds and severity labels are starting points. Change the container # selector to the label your log collector sets, such as job or service. # Setup, window sizing and per-alert notes are in docs/monitoring.md. groups: - name: fclones rules: # A deadman. It fires on silence, so it catches a stuck schedule that # logs nothing. The 28h window fits the default SCAN_TIMEOUT and # SCAN_INTERVAL. docs/monitoring.md shows how to resize it. - alert: FclonesScanStalled expr: | absent_over_time({container="fclones"} |= "scan complete" [28h]) for: 15m labels: severity: warning annotations: summary: "No fclones scan has completed in 28h" description: > No `scan complete` line has arrived in 28h. Check for a stuck schedule, a scan past its phase timeout, or no outside trigger with SCAN_INTERVAL=off. Also check that the container runs and its logs reach Loki. - alert: FclonesLinkEstablished expr: | sum by (files_deduped, reclaimed_human) ( count_over_time( {container="fclones"} |= "action complete" | logfmt | action="link" | files_deduped > 0 [15m] ) ) > 0 for: 0m labels: severity: info annotations: summary: "fclones linked {{ $labels.files_deduped }} duplicate files and reclaimed {{ $labels.reclaimed_human }}" description: > fclones replaced {{ $labels.files_deduped }} duplicate files with hardlinks and freed {{ $labels.reclaimed_human }}. The scan's `duplicate file` log lines list the linked paths. This is a success notice and needs no action. - alert: FclonesActionReclaimedNothing expr: | sum(count_over_time({container="fclones"} |= "action reclaimed nothing" [2h])) > 0 for: 0m labels: severity: warning annotations: summary: "fclones deduplicated none of the duplicates it found" description: > A link, remove or dedupe run found duplicates and freed no space. Check that the container's user can write to the scanned folders. For dedupe, check that the filesystem supports reflinks. The container stays unhealthy until a run frees space. - alert: FclonesFormatDrift expr: | sum(count_over_time({container="fclones"} |= "possible fclones format drift" [2h])) > 0 for: 0m labels: severity: warning annotations: summary: "fclones output-format drift detected, so action stats may be unreliable" description: > The container did not recognize the summary line of the fclones action, so files_deduped and bytes_reclaimed may read zero after real work. The run still succeeds. Check the fclones version against the summary formats the container recognizes.