Configuration¶
smartscan reads an optional TOML config file. When --config is not specified on
the command line, the first file found among the following is used:
~/.config/smartscan/smartscan.toml(XDG user config)/etc/smartscan/smartscan.toml(system-wide config)
Pass --config <path> to use a specific file.
All keys shown below with their default values:
# ── Output ─────────────────────────────────────────────────────
# Output format: "table" or "json"
format = "table"
# Custom database path
db_path = "/var/lib/smartscan/smartscan.db"
# Custom log file path
log_file = "/var/log/smartscan/smartscan.log"
# Log level: "DEBUG", "INFO", "WARNING", or "ERROR"
log_level = "WARNING"
# Regex patterns to exclude disk devices by symlink name or resolved path.
# Applies to both `collect` and `lsblk` subcommands.
# Useful for filtering out optical drives, loop devices, ZFS zvols, etc.
# Example: exclude_patterns = ["BD-RE", '^/dev/(loop|zd)\d+']
exclude_patterns = []
# ── collect ────────────────────────────────────────────────────
[collect]
# Skip database writes (run once without saving)
no_save = false
# ── query ───────────────────────────────────────────────────────
[query]
# Restrict to records from this date (YYYY-MM-DD)
# since = "2025-01-01"
# Restrict to records until this date
# until = "2025-12-31"
# Show only records from the last N days (overrides `since`)
# last_days = 7
# Enable automatic deduplication of unchanged records (default: true)
compact_enabled = true
# Time window in minutes for change-detection compaction (default: 30)
compact_window_minutes = 30
# ── prune ─────────────────────────────────────────────────────
[prune]
# Time window in minutes for redundancy detection (default: 30)
window_minutes = 30
# ── lsblk ────────────────────────────────────────────────────
[lsblk]
# Restrict to specific /dev/disk/ source directories
# (by-id, by-path, by-diskseq; default: all when empty)
# source = ["by-id", "by-path"]
# ── Threshold alerts ────────────────────────────────────────────
[thresholds]
# Master switch: set to false to disable all threshold checks
enabled = true
# Alert if disk temperature exceeds this value (Celsius)
temperature_celsius = 50
# Alert if any sectors have been reallocated (surface defects)
reallocated_sector_ct = 0
# Alert if sectors are pending remap (often indicates instability)
current_pending_sector = 0
# Alert if sectors are uncorrectable offline (possible surface damage)
offline_uncorrectable = 0
# Alert if the reallocation event counter has increased
reallocated_event_count = 0
# Alert if UDMA CRC errors occur (typically a cabling or controller issue)
udma_crc_error_count = 0
# Alert if the ATA SMART error log contains entries
ata_smart_error_log_count = 0
# Alert if the disk has retried spinning up (motor/bearing wear)
spin_retry_count = 0
# Alert if head load/unload cycle count exceeds this value
# (600_000 is typical for many consumer hard drives; enterprise drives often rated higher)
load_cycle_count = 600_000
# ── LLM-based health analysis ──────────────────────────────────
[llm]
# Set to true to enable LLM analysis (requires API key)
enabled = false
# LLM API provider: "openai" (default) for OpenAI-compatible APIs,
# "anthropic" for Anthropic's native Messages API
provider = "openai"
# Full API URL, must include the path, e.g.,
# https://api.openai.com/v1/chat/completions for OpenAI
# https://api.anthropic.com/v1/messages for Anthropic
api_url = "https://api.openai.com/v1/chat/completions"
# Your API key (or set OPENAI_API_KEY / ANTHROPIC_API_KEY environment variable)
api_key = ""
# Model name as recognised by the API
model = "gpt-4o-mini"
# Maximum tokens in the model response (output limit, not input)
max_tokens = 4096
# HTTP request timeout in seconds
timeout = 120
# Controls randomness: 0.0 = deterministic, higher = more creative
temperature = 0.3
# Seconds to wait between LLM calls when processing multiple disks (avoids rate limits)
delay = 0.0
# Language for LLM responses. Set to "zh" for Chinese (简体中文); null/omitted for English.
# lang = "zh"
# System prompt sent as the first message to guide the model's behaviour
system_prompt = """\
You are a hard drive health diagnostic expert analyzing SMART data.
Examine the provided SMART attributes and give a concise assessment:
1. Overall health status: HEALTHY / WARNING / CRITICAL
2. Key concerns with specific metric values (if any)
3. Recommended action (one sentence)
Be factual and conservative. Do not cause unnecessary alarm for borderline values.
If all metrics are within normal ranges, state the drive is healthy.
If you cannot make a definitive assessment, say so honestly.
Additionally, check the self-test log for the most recent long (extended)
self-test and compare its lifetime hours against the drive's total power-on
hours. If a significant portion of the drive's lifetime has passed since the
last long self-test, recommend running one."""
# System prompt for batch (summary) LLM analysis across all disks
batch_system_prompt = """\
You are a hard drive health diagnostic expert analyzing SMART data from multiple disk devices.
Provide a comprehensive assessment:
1. Overall health status for each disk (HEALTHY / WARNING / CRITICAL)
2. Key concerns with specific metric values (if any)
3. Any patterns or correlations across all disks (e.g. shared backplane issues)
4. Prioritised recommended actions
Be factual and conservative. Do not cause unnecessary alarm for borderline values.
If all metrics are within normal ranges, state each drive is healthy.
If you cannot make a definitive assessment for a given drive, say so honestly.
Additionally, check each drive's self-test log for the most recent long (extended)
self-test and compare its lifetime hours against the drive's total power-on
hours. If a significant portion of the lifetime has passed since the
last long self-test, recommend running one."""
# ── Notification channels ──────────────────────────────────────
[notify]
[notify.telegram]
enabled = false
bot_token = ""
chat_id = ""
[notify.dingtalk]
enabled = false
webhook_url = ""
secret = ""
[notify.feishu]
enabled = false
webhook_url = ""
secret = ""
To force LLM analysis on healthy disks (no threshold alerts), use:
sudo smartscan collect --llm all
See LLM Examples for provider-specific configuration snippets.