Operations Automation
EnerOS has built-in complete operations automation capabilities, covering On-call scheduling, Runbook automatic execution, automatic autoscaling, backup recovery and other scenarios, reducing dependence on manual operations and improving the stability of power production environments. Operations automation is provided by the eneros-ops crate, deeply integrated with the alert system, health checks, and security gateway.
Automation Architecture
┌──────────────────────────────────────────────────────────┐
│ Monitoring and Alert Sources │
│ Prometheus / Health Probe / IDS / SLO Violation │
└──────────────────────┬───────────────────────────────────┘
│
┌──────────────────────▼───────────────────────────────────┐
│ Automation Decision Layer │
│ Alert Router ─▶ Runbook Engine ─▶ Approval Gate │
│ │ │
│ ┌────────┴────────┐ │
│ ▼ ▼ │
│ Action Executor On-call Notifier │
└──────────────────────┬───────────────────────────────────┘
│
┌──────────────────────▼───────────────────────────────────┐
│ Execution and Rollback Layer │
│ Service Restart / Scale Up-Down / Backup / Restore │
│ All actions fall into WORM audit chain │
└──────────────────────────────────────────────────────────┘
| Module | Responsibility | Trigger |
|---|---|---|
| On-call Schedule | Scheduling and escalation | Alert trigger |
| Runbook Engine | Automated playbook execution | Alert / scheduled |
| Autoscaler | Resource scaling | Metric threshold |
| Backup Manager | Backup and recovery | Scheduled / manual |
| Health Monitor | Health probing and self-healing | Periodic / event |
| Report Scheduler | Scheduled reports | Scheduled |
On-call Management
Supports multi-team, multi-level scheduling and escalation policies:
use eneros_ops::oncall::{OncallSchedule, Rotation, EscalationPolicy, Day, Time};
use std::time::Duration;
let schedule = OncallSchedule::new()
.rotation(Rotation::weekly()
.members(vec!["alice", "bob", "carol"])
.handoff(Day::Monday, Time::from_hms(9, 0, 0)))
.escalation(EscalationPolicy::new()
.level(1, Duration::from_secs(5 * 60)) // 5 min no response → L2
.level(2, Duration::from_secs(15 * 60)) // 15 min → L3
.level(3, Duration::from_secs(30 * 60))) // 30 min → L4
.timezone("Asia/Shanghai")
.follow_the_sun(true) // Follow-the-sun mode
.override(OncallOverride::new()
.user("dave")
.start("2026-07-10T09:00:00+08:00")
.end("2026-07-15T18:00:00+08:00"));
schedule.activate().await?;
Escalation Level Description
| Level | Trigger Condition | Notification Channel | Response Target |
|---|---|---|---|
| L1 | Alert generated | DingTalk / WeCom | 5 minutes |
| L2 | L1 no response 5 min | SMS + DingTalk | 15 minutes |
| L3 | L2 no response 15 min | Phone call | 30 minutes |
| L4 | L3 no response 30 min | Phone + email to supervisor | 60 minutes |
Runbook Automation
Transforms operations playbooks into executable Runbooks, automatically executed when alerts trigger. Runbooks support conditional branching, parallel steps, and manual approval nodes.
use eneros_ops::runbook::{Runbook, Step, Trigger, Condition, Action};
let runbook = Runbook::new("high-cpu-agent")
.trigger(Trigger::alert("agent_cpu_90"))
.step(Step::check(health_check, "Service health check"))
.step(Step::collect_diagnostic()
.snapshot(Snapshot::heap_profile())
.snapshot(Snapshot::thread_dump())
.snapshot(Snapshot::metrics_window(Duration::from_secs(300))))
.step(Step::conditional(
Condition::cpu_high_for(Duration::from_secs(60)),
Step::sequence(vec![
Step::restart_service("agent-runtime"),
Step::wait(Duration::from_secs(30)),
Step::verify(ServiceHealth::healthy()),
]),
))
.step(Step::approval(
"Emergency scaling requires supervisor approval",
Duration::from_secs(300),
Approver::role("ops_lead"),
))
.step(Step::notify_oncall()
.channel(NotifyChannel::DingTalk));
runbook.register(&ops).await?;
Runbook Library
| Runbook | Trigger Condition | Action Chain | Estimated Duration |
|---|---|---|---|
| high-cpu | CPU > 90% for 5min | Diagnose → Restart → Verify | 2 minutes |
| disk-full | Disk > 85% | Clean logs → Alert | 30 seconds |
| agent-crash | Agent process exit | Restart → Notify → Collect core dump | 5 seconds |
| tsdb-slow | Query P99 > 1s | Rebuild index → Switch read-only replica | 5 minutes |
| cert-expire | Certificate 30 days to expiry | Renew → Reload → Verify | 30 seconds |
| memory-leak | Memory continuously growing > 1h | Dump → Restart → Notify | 1 minute |
| tls-handshake-fail | mTLS failure rate > 5% | Check CA → Reload certificate | 1 minute |
| replica-lag | Replica lag > 10s | Reset replication → Notify | 2 minutes |
Runbook Configuration Parameters
| Parameter | Default | Description |
|---|---|---|
| timeout | 300s | Single Runbook execution timeout |
| step_timeout | 60s | Single step execution timeout |
| retry | 3 times | Failure retry count |
| parallel_steps | 4 | Maximum parallel steps |
| require_approval | false | Whether manual approval required |
| collect_diagnostic | true | Automatically collect diagnostic info |
Automatic Autoscaling
Automatically adjusts resources based on multi-dimensional metrics, supporting both Predictive and Reactive strategies:
use eneros_ops::autoscale::{Autoscaler, Rule, Strategy};
let scaler = Autoscaler::new()
.target("agent-runtime")
.min_instances(2)
.max_instances(10)
.strategy(Strategy::reactive())
.rule(Rule::cpu(70, 90)) // CPU 70% scale up, 90% emergency scale up
.rule(Rule::memory(80, 95))
.rule(Rule::queue_depth(1000, 5000))
.rule(Rule::custom("inflight_requests", 500, 2000))
.cooldown(Duration::from_secs(300))
.scale_up_step(2) // Scale up 2 instances each time
.scale_down_step(1)
.grace_period(Duration::from_secs(60));
scaler.activate().await?;
Predictive Autoscaling
Scales up in advance based on historical load predictions:
use eneros_ops::autoscale::predictive::{PredictiveScaler, ForecastModel};
let predictive = PredictiveScaler::new()
.model(ForecastModel::prophet()
.history(Duration::from_secs(86400 * 30)) // 30 days history
.horizon(Duration::from_secs(3600)) // 1 hour prediction
.confidence(0.95))
.lookahead(Duration::from_secs(600)) // 10 minutes ahead
.min_confidence(0.80);
predictive.activate().await?;
Autoscaling Rule Parameters
| Rule | Scale Up Threshold | Scale Down Threshold | Evaluation Window |
|---|---|---|---|
| cpu | > 70% | < 30% | 5 minutes |
| memory | > 80% | < 40% | 5 minutes |
| queue_depth | > 1000 | < 200 | 1 minute |
| latency_p99 | > 500ms | < 100ms | 5 minutes |
| inflight_requests | > 500 | < 100 | 1 minute |
Real-time Domain Does Not Participate in Automatic Autoscaling
Real-time domain resources are statically bound at deployment time, avoiding dynamic scheduling that would break determinism. Autoscaling only applies to the general domain. Real-time domain scaling requires manual approval before execution.
Backup and Recovery
Supports full, incremental, and continuous backups, all backups are encrypted and written to object storage:
use eneros_ops::backup::{BackupManager, BackupSpec, BackupTarget, KeyId, Verification};
let backup = BackupManager::new()
.schedule("daily-full", BackupSpec::full()
.target(BackupTarget::S3("s3://eneros-backup"))
.encryption(KeyId::from("backup-key"))
.compression(Compression::Zstd { level: 9 })
.retention(Duration::from_secs(86400 * 30))
.verify(Verification::checksum()))
.schedule("5min-incremental", BackupSpec::incremental()
.target(BackupTarget::S3("s3://eneros-backup"))
.retention(Duration::from_secs(86400 * 7)))
.schedule("continuous-wal", BackupSpec::continuous_wal()
.target(BackupTarget::S3("s3://eneros-backup/wal"))
.retention(Duration::from_secs(86400)));
backup.start().await?;
Recovery Operation
use eneros_ops::backup::{Restore, RestoreTarget, RestorePoint};
let restore = Restore::new()
.from(RestorePoint::latest())
.to(RestoreTarget::NewCluster("staging-restore"))
.include(vec!["topology", "timeseries", "agents"])
.verify(Verification::data_integrity())
.verify(Verification::service_health());
restore.execute().await?;
Recovery Drills
Regularly execute recovery drills automatically to verify backup validity:
backup.drill()
.restore_to("staging")
.verify(Verification::data_integrity())
.verify(Verification::service_health())
.verify(Verification::slo_met(99.9))
.schedule(Duration::from_secs(86400 * 7)) // Weekly
.notify_on_failure(vec!["ops@grid.com"])
.run().await?;
Backup Strategy Comparison
| Strategy | Frequency | RPO | Storage | Applicable |
|---|---|---|---|---|
| Full | Daily | 24h | High | Long-term archival |
| Incremental | Every 5 min | 5min | Low | Daily recovery |
| WAL Continuous | Real-time | ≈0 | Medium | Disaster recovery |
| Cross-region Replication | Real-time | ≈0 | High | DR scenarios |
Health Check and Self-Healing
Multi-dimensional health probing and automatic self-healing:
use eneros_ops::health::{HealthMonitor, Probe, ProbeType};
let monitor = HealthMonitor::new()
.probe(Probe::http("agent-runtime", "/health", 200)
.interval(Duration::from_secs(10))
.timeout(Duration::from_secs(2))
.failure_threshold(3))
.probe(Probe::tcp("realtime-domain", 6080)
.interval(Duration::from_secs(5)))
.probe(Probe::custom("tsdb", check_tsdb_health)
.interval(Duration::from_secs(30)))
.probe(Probe::grpc("kernel", "/grpc.health.v1.Health/Check")
.interval(Duration::from_secs(10)))
.on_unhealthy(|service, status| async move {
match status.failures {
1..=2 => SelfHealing::restart(service).await,
3..=5 => SelfHealing::replace(service).await,
_ => SelfHealing::escalate(service).await,
}
});
monitor.start().await?;
Self-Healing Action Matrix
| Failure Count | Action | Impact |
|---|---|---|
| 1-2 | Restart service | Brief interruption |
| 3-5 | Replace instance | Traffic switchover |
| 6+ | Escalate to manual | Enter maintenance mode |
Performance Metrics
| Operation | Latency | Remarks |
|---|---|---|
| Runbook trigger to execution | < 1s | Including alert routing |
| Autoscaling decision | < 5s | Including metric aggregation |
| Incremental backup (1GB data) | < 30s | After compression and encryption |
| Full recovery (100GB) | < 10min | Including verification |
| Self-healing restart Agent | < 3s | Including health check |
| On-call notification delivery | < 5s | DingTalk / SMS |
| Health check execution | < 100ms | Single Probe |
| Recovery drill startup | < 30s | Including resource allocation |
Notification Channels
| Channel | Applicable | Latency | Retry |
|---|---|---|---|
| Non-urgent | 30s | 3 times | |
| SMS | High priority | 5s | 3 times |
| DingTalk / WeCom | Team collaboration | 2s | 5 times |
| Webhook | External system integration | 1s | 5 times |
| Phone call | L3 level alerts | 10s | Until answered |
| Slack | International teams | 2s | 3 times |
Relationship with Other Capabilities
- High Availability Enhancement: Operations automation is the execution layer of HA guarantees, see High Availability Enhancement
- Multi-tenant Isolation: Operations actions isolated by tenant, see Multi-tenant and Isolation
- Safety Guard: Operations commands also pass through safety gateway, see Safety Guard
- Zero Trust: All operations actions fall into audit chain, see Zero Trust and Security Enhancement
- AIOps: Alert clustering and root cause analysis drive Runbook triggers
Related Documentation
- High Availability Enhancement — Operations supports high availability
- Multi-tenant and Isolation — Tenant-level operations
- Safety Guard — Operations commands also pass through safety gateway
- Zero Trust and Security Enhancement — Operations action audit
- Agent Intelligence Advanced — AIOps intelligent operations