Skip to content

Commit eb3b63a

Browse files
improved workload insights; ui redesign
1 parent 9905977 commit eb3b63a

File tree

10 files changed

+2306
-498
lines changed

10 files changed

+2306
-498
lines changed

INSIGHTS.md

Lines changed: 275 additions & 120 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ Quick access:
9595
* Full guide: [`INSIGHTS.md`](./INSIGHTS.md)
9696
* Web UI path: `Advanced -> Insights Analysis`
9797
* Output: Dashboard insights panel + `Download Summary` JSON (`insights` section)
98+
* Includes explain support matrix, status/reason glossary, confidence model, troubleshooting, and limitations
9899

99100
## The Interactive UI
100101

config.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,25 @@ csv_export_enabled: false
5959
csv_export_append: false # If true, appends to the file. If false, overwrites it.
6060
csv_export_path: "/tmp/plgm_metrics_export.csv"
6161

62+
# ==============================================================================
63+
# Post-Run Insights (Slow Query / Index Analysis)
64+
# ==============================================================================
65+
# Insights are generated after workload completion.
66+
# Explain mode is post-run only and does not execute during the measured workload window.
67+
insights_enabled: true
68+
insights_sampling_rate: 0.10
69+
insights_slow_threshold_ms: 200
70+
insights_max_events: 5000
71+
insights_max_groups: 300
72+
insights_explain_enabled: false
73+
insights_explain_top_n: 5
74+
insights_explain_max_time_ms: 1000
75+
# Modes: high_only (default), medium_only, critical_only, high_and_low
76+
insights_explain_severity_mode: "high_only"
77+
insights_explain_workers: 1
78+
insights_explain_retries: 1
79+
insights_explain_backoff_ms: 150
80+
6281
# ==============================================================================
6382
# Workload Definition
6483
# ==============================================================================

internal/config/config.go

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,18 @@ type AppConfig struct {
5454
CSVExportAppend bool `yaml:"csv_export_append"`
5555
CSVExportPath string `yaml:"csv_export_path"`
5656

57-
InsightsEnabled bool `yaml:"insights_enabled"`
58-
InsightsSamplingRate float64 `yaml:"insights_sampling_rate"`
59-
InsightsSlowThresholdMs int `yaml:"insights_slow_threshold_ms"`
60-
InsightsMaxEvents int `yaml:"insights_max_events"`
61-
InsightsMaxGroups int `yaml:"insights_max_groups"`
62-
InsightsExplainEnabled bool `yaml:"insights_explain_enabled"`
63-
InsightsExplainTopN int `yaml:"insights_explain_top_n"`
64-
InsightsExplainMaxTimeMS int `yaml:"insights_explain_max_time_ms"`
57+
InsightsEnabled bool `yaml:"insights_enabled"`
58+
InsightsSamplingRate float64 `yaml:"insights_sampling_rate"`
59+
InsightsSlowThresholdMs int `yaml:"insights_slow_threshold_ms"`
60+
InsightsMaxEvents int `yaml:"insights_max_events"`
61+
InsightsMaxGroups int `yaml:"insights_max_groups"`
62+
InsightsExplainEnabled bool `yaml:"insights_explain_enabled"`
63+
InsightsExplainTopN int `yaml:"insights_explain_top_n"`
64+
InsightsExplainMaxTimeMS int `yaml:"insights_explain_max_time_ms"`
65+
InsightsExplainSeverityMode string `yaml:"insights_explain_severity_mode"`
66+
InsightsExplainWorkers int `yaml:"insights_explain_workers"`
67+
InsightsExplainRetries int `yaml:"insights_explain_retries"`
68+
InsightsExplainBackoffMS int `yaml:"insights_explain_backoff_ms"`
6569
}
6670

6771
type WebUIConfig struct {
@@ -169,6 +173,10 @@ func applyUIDefaults(cfg *AppConfig) {
169173
cfg.InsightsExplainEnabled = false
170174
cfg.InsightsExplainTopN = 5
171175
cfg.InsightsExplainMaxTimeMS = 1000
176+
cfg.InsightsExplainSeverityMode = "high_only"
177+
cfg.InsightsExplainWorkers = 1
178+
cfg.InsightsExplainRetries = 1
179+
cfg.InsightsExplainBackoffMS = 150
172180
}
173181

174182
// applyBaseDefaults sets low-level engine safety limits & remaining UI limits
@@ -204,6 +212,20 @@ func applyBaseDefaults(cfg *AppConfig) {
204212
if cfg.InsightsExplainMaxTimeMS <= 0 {
205213
cfg.InsightsExplainMaxTimeMS = 1000
206214
}
215+
switch cfg.InsightsExplainSeverityMode {
216+
case "high_and_low", "medium_only", "critical_only", "high_only":
217+
default:
218+
cfg.InsightsExplainSeverityMode = "high_only"
219+
}
220+
if cfg.InsightsExplainWorkers <= 0 {
221+
cfg.InsightsExplainWorkers = 1
222+
}
223+
if cfg.InsightsExplainRetries < 0 {
224+
cfg.InsightsExplainRetries = 0
225+
}
226+
if cfg.InsightsExplainBackoffMS < 0 {
227+
cfg.InsightsExplainBackoffMS = 0
228+
}
207229

208230
// Web UI Port
209231
if cfg.WebUI.Port <= 0 {
@@ -567,6 +589,24 @@ func applyEnvOverrides(cfg *AppConfig) map[string]bool {
567589
cfg.InsightsExplainMaxTimeMS = n
568590
}
569591
}
592+
if v := os.Getenv("PLGM_INSIGHTS_EXPLAIN_SEVERITY_MODE"); v != "" {
593+
cfg.InsightsExplainSeverityMode = v
594+
}
595+
if v := os.Getenv("PLGM_INSIGHTS_EXPLAIN_WORKERS"); v != "" {
596+
if n, err := strconv.Atoi(v); err == nil && n > 0 {
597+
cfg.InsightsExplainWorkers = n
598+
}
599+
}
600+
if v := os.Getenv("PLGM_INSIGHTS_EXPLAIN_RETRIES"); v != "" {
601+
if n, err := strconv.Atoi(v); err == nil && n >= 0 {
602+
cfg.InsightsExplainRetries = n
603+
}
604+
}
605+
if v := os.Getenv("PLGM_INSIGHTS_EXPLAIN_BACKOFF_MS"); v != "" {
606+
if n, err := strconv.Atoi(v); err == nil && n >= 0 {
607+
cfg.InsightsExplainBackoffMS = n
608+
}
609+
}
570610

571611
return overrides
572612
}

internal/config/config_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ func TestLoadAppConfigWebUIDefaultsAndBaseDefaults(t *testing.T) {
2828
if cfg.FindPercent+cfg.UpdatePercent+cfg.DeletePercent+cfg.InsertPercent+cfg.AggregatePercent+cfg.TransactionPercent+cfg.BulkInsertPercent != 100 {
2929
t.Fatalf("expected normalized percentages to total 100")
3030
}
31+
if cfg.InsightsExplainWorkers != 1 || cfg.InsightsExplainRetries != 1 || cfg.InsightsExplainBackoffMS != 150 || cfg.InsightsExplainSeverityMode != "high_only" {
32+
t.Fatalf("expected explain defaults workers=1 retries=1 backoff=150 mode=high_only, got workers=%d retries=%d backoff=%d mode=%q", cfg.InsightsExplainWorkers, cfg.InsightsExplainRetries, cfg.InsightsExplainBackoffMS, cfg.InsightsExplainSeverityMode)
33+
}
3134
}
3235

3336
func TestLoadAppConfigWithYAMLAndEnvOverrides(t *testing.T) {
@@ -133,3 +136,35 @@ func TestApplyBaseDefaultsPreservesExplicitValues(t *testing.T) {
133136
t.Fatalf("expected csv path default when export enabled")
134137
}
135138
}
139+
140+
func TestApplyEnvOverridesInsightsExplainRuntimeSettings(t *testing.T) {
141+
cfg := &AppConfig{}
142+
t.Setenv("PLGM_INSIGHTS_EXPLAIN_WORKERS", "3")
143+
t.Setenv("PLGM_INSIGHTS_EXPLAIN_RETRIES", "2")
144+
t.Setenv("PLGM_INSIGHTS_EXPLAIN_BACKOFF_MS", "250")
145+
t.Setenv("PLGM_INSIGHTS_EXPLAIN_SEVERITY_MODE", "medium_only")
146+
147+
_ = applyEnvOverrides(cfg)
148+
applyBaseDefaults(cfg)
149+
150+
if cfg.InsightsExplainWorkers != 3 {
151+
t.Fatalf("expected explain workers override 3, got %d", cfg.InsightsExplainWorkers)
152+
}
153+
if cfg.InsightsExplainRetries != 2 {
154+
t.Fatalf("expected explain retries override 2, got %d", cfg.InsightsExplainRetries)
155+
}
156+
if cfg.InsightsExplainBackoffMS != 250 {
157+
t.Fatalf("expected explain backoff override 250, got %d", cfg.InsightsExplainBackoffMS)
158+
}
159+
if cfg.InsightsExplainSeverityMode != "medium_only" {
160+
t.Fatalf("expected explain severity mode override medium_only, got %q", cfg.InsightsExplainSeverityMode)
161+
}
162+
}
163+
164+
func TestApplyBaseDefaultsNormalizesUnknownExplainSeverityMode(t *testing.T) {
165+
cfg := &AppConfig{InsightsExplainSeverityMode: "unexpected_mode"}
166+
applyBaseDefaults(cfg)
167+
if cfg.InsightsExplainSeverityMode != "high_only" {
168+
t.Fatalf("expected invalid explain severity mode to normalize to high_only, got %q", cfg.InsightsExplainSeverityMode)
169+
}
170+
}

0 commit comments

Comments
 (0)