feat: comprehensive INFO/WARN/ERROR logging across all controller modules

Add structured operational logging at INFO, WARN, and ERROR levels to
every controller module. Standardize custom prefixes ([GEO], [SCHED],
[SYNC]) to use [INFO/WARN/ERROR] [module] format. Fix misleveled logs
(WARN->ERROR for data loss scenarios, WARN->INFO for routine operations).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-26 19:58:27 +01:00
parent 95c821deb2
commit 8e61cd7ec4
44 changed files with 326 additions and 44 deletions
@@ -41,7 +41,7 @@ func (m *Manager) OnStackStop(_ context.Context, stackName string) {
ac, err := m.buildApplyContext(provider, target)
if err != nil {
m.logger.Printf("[WARN] Cannot build context for integration %s revoke: %v", key, err)
m.logger.Printf("[WARN] [integrations] Cannot build context for integration %s revoke: %v", key, err)
continue
}
@@ -49,7 +49,7 @@ func (m *Manager) OnStackStop(_ context.Context, stackName string) {
m.logger.Printf("[DEBUG] [integrations] OnStackStop: revoking %s", key)
}
if err := handler.Revoke(ac); err != nil {
m.logger.Printf("[WARN] Integration revoke on stop failed for %s: %v", key, err)
m.logger.Printf("[WARN] [integrations] Integration revoke on stop failed for %s: %v", key, err)
}
if provider == stackName {
@@ -58,7 +58,7 @@ func (m *Manager) OnStackStop(_ context.Context, stackName string) {
state.Status = "target_unavailable"
}
_ = m.sett.SetIntegrationState(key, state)
m.logger.Printf("[INFO] Integration %s suspended (stack %s stopped)", key, stackName)
m.logger.Printf("[INFO] [integrations] Integration %s suspended (stack %s stopped)", key, stackName)
}
}
@@ -126,12 +126,12 @@ func (m *Manager) OnStackStart(_ context.Context, stackName string) {
ac, err := m.buildApplyContext(provider, target)
if err != nil {
m.logger.Printf("[WARN] Cannot re-apply integration %s on start: %v", key, err)
m.logger.Printf("[WARN] [integrations] Cannot re-apply integration %s on start: %v", key, err)
continue
}
if err := handler.Apply(ac); err != nil {
m.logger.Printf("[WARN] Integration re-apply on start failed for %s: %v", key, err)
m.logger.Printf("[ERROR] [integrations] Integration re-apply on start failed for %s: %v", key, err)
state.Status = "error"
state.LastError = err.Error()
_ = m.sett.SetIntegrationState(key, state)
@@ -141,7 +141,7 @@ func (m *Manager) OnStackStart(_ context.Context, stackName string) {
state.Status = "active"
state.LastError = ""
_ = m.sett.SetIntegrationState(key, state)
m.logger.Printf("[INFO] Integration %s re-activated (stack %s started)", key, stackName)
m.logger.Printf("[INFO] [integrations] Integration %s re-activated (stack %s started)", key, stackName)
}
}
@@ -186,6 +186,6 @@ func (m *Manager) OnStackRemove(_ context.Context, stackName string) {
}
_ = m.sett.RemoveIntegrationState(key)
m.logger.Printf("[INFO] Integration %s removed (stack %s removed)", key, stackName)
m.logger.Printf("[INFO] [integrations] Integration %s removed (stack %s removed)", key, stackName)
}
}
@@ -125,6 +125,7 @@ func (m *Manager) Toggle(ctx context.Context, provider, target string, enable bo
start := time.Now()
if err := handler.Apply(ac); err != nil {
m.logger.Printf("[ERROR] [integrations] Integration %s apply failed: %v", key, err)
if m.isDebug() {
m.logger.Printf("[DEBUG] [integrations] Toggle: Apply failed for %s in %v: %v", key, time.Since(start), err)
}
@@ -210,6 +211,7 @@ func (m *Manager) ListForProvider(providerSlug string) []StatusInfo {
func (m *Manager) buildApplyContext(provider, target string) (*ApplyContext, error) {
provStack, ok := m.stacks.GetStack(provider)
if !ok {
m.logger.Printf("[WARN] [integrations] Failed to build context for %s:%s: provider stack not found", provider, target)
return nil, fmt.Errorf("szolgáltató stack %q nem található", provider)
}
@@ -299,6 +301,7 @@ func (m *Manager) loadDecryptedEnv(s *stacks.Stack) map[string]string {
stackDir := filepath.Dir(s.ComposePath)
cfg := stacks.LoadAppConfig(stackDir)
if cfg == nil {
m.logger.Printf("[WARN] [integrations] Failed to load env for %s: app config is nil", s.Name)
return nil
}
if m.encKey != nil {
@@ -13,6 +13,7 @@ type OnlyOfficeFileBrowserHandler struct{}
func (h *OnlyOfficeFileBrowserHandler) Apply(ac *ApplyContext) error {
jwtSecret := ac.ProviderEnv["JWT_SECRET"]
if jwtSecret == "" {
ac.Logger.Printf("[ERROR] [integrations] OnlyOffice-FileBrowser apply: JWT_SECRET not set")
return fmt.Errorf("OnlyOffice JWT_SECRET nincs beállítva — telepítsd újra az alkalmazást")
}
@@ -21,6 +22,7 @@ func (h *OnlyOfficeFileBrowserHandler) Apply(ac *ApplyContext) error {
subdomain = ac.ProviderMeta.Subdomain
}
if subdomain == "" {
ac.Logger.Printf("[ERROR] [integrations] OnlyOffice-FileBrowser apply: subdomain unknown")
return fmt.Errorf("OnlyOffice aldomain nem ismert")
}
@@ -31,6 +33,7 @@ func (h *OnlyOfficeFileBrowserHandler) Apply(ac *ApplyContext) error {
configData, err := os.ReadFile(configPath)
if err != nil {
ac.Logger.Printf("[ERROR] [integrations] OnlyOffice-FileBrowser apply: %v", err)
return fmt.Errorf("FileBrowser config olvasási hiba: %w", err)
}
@@ -47,10 +50,12 @@ func (h *OnlyOfficeFileBrowserHandler) Apply(ac *ApplyContext) error {
// Atomic write
tmpPath := configPath + ".tmp"
if err := os.WriteFile(tmpPath, []byte(configStr), 0644); err != nil {
ac.Logger.Printf("[ERROR] [integrations] OnlyOffice-FileBrowser apply: %v", err)
return fmt.Errorf("config írási hiba: %w", err)
}
if err := os.Rename(tmpPath, configPath); err != nil {
_ = os.Remove(tmpPath)
ac.Logger.Printf("[ERROR] [integrations] OnlyOffice-FileBrowser apply: %v", err)
return fmt.Errorf("config átnevezési hiba: %w", err)
}
@@ -67,6 +72,7 @@ func (h *OnlyOfficeFileBrowserHandler) Revoke(ac *ApplyContext) error {
if os.IsNotExist(err) {
return nil
}
ac.Logger.Printf("[ERROR] [integrations] OnlyOffice-FileBrowser revoke: %v", err)
return fmt.Errorf("config olvasási hiba: %w", err)
}
@@ -79,10 +85,12 @@ func (h *OnlyOfficeFileBrowserHandler) Revoke(ac *ApplyContext) error {
tmpPath := configPath + ".tmp"
if err := os.WriteFile(tmpPath, []byte(cleaned), 0644); err != nil {
ac.Logger.Printf("[ERROR] [integrations] OnlyOffice-FileBrowser revoke: %v", err)
return fmt.Errorf("config írási hiba: %w", err)
}
if err := os.Rename(tmpPath, configPath); err != nil {
_ = os.Remove(tmpPath)
ac.Logger.Printf("[ERROR] [integrations] OnlyOffice-FileBrowser revoke: %v", err)
return fmt.Errorf("config átnevezési hiba: %w", err)
}
@@ -14,6 +14,7 @@ type OnlyOfficeNextcloudHandler struct{}
func (h *OnlyOfficeNextcloudHandler) Apply(ac *ApplyContext) error {
jwtSecret := ac.ProviderEnv["JWT_SECRET"]
if jwtSecret == "" {
ac.Logger.Printf("[ERROR] [integrations] OnlyOffice-Nextcloud apply: JWT_SECRET not set")
return fmt.Errorf("OnlyOffice JWT_SECRET nincs beállítva")
}
@@ -22,6 +23,7 @@ func (h *OnlyOfficeNextcloudHandler) Apply(ac *ApplyContext) error {
subdomain = ac.ProviderMeta.Subdomain
}
if subdomain == "" {
ac.Logger.Printf("[ERROR] [integrations] OnlyOffice-Nextcloud apply: subdomain unknown")
return fmt.Errorf("OnlyOffice aldomain nem ismert")
}
@@ -72,6 +74,7 @@ func (h *OnlyOfficeNextcloudHandler) Apply(ac *ApplyContext) error {
ac.Logger.Printf("[DEBUG] Nextcloud occ: tolerated — %s", strings.TrimSpace(string(out)))
continue
}
ac.Logger.Printf("[ERROR] [integrations] OnlyOffice-Nextcloud apply: occ %s failed: %v", cmd.args[len(cmd.args)-1], err)
return fmt.Errorf("occ parancs sikertelen (%s): %v (kimenet: %s)", cmd.args[len(cmd.args)-1], err, strings.TrimSpace(string(out)))
}
ac.Logger.Printf("[DEBUG] Nextcloud occ %s: ok", strings.Join(cmd.args[7:], " "))
@@ -96,6 +99,7 @@ func (h *OnlyOfficeNextcloudHandler) Revoke(ac *ApplyContext) error {
ac.Logger.Printf("[DEBUG] Nextcloud occ app:disable skipped — %s", strings.TrimSpace(outStr))
return nil
}
ac.Logger.Printf("[ERROR] [integrations] OnlyOffice-Nextcloud revoke: occ app:disable failed: %v", err)
return fmt.Errorf("occ app:disable sikertelen: %v (kimenet: %s)", err, strings.TrimSpace(outStr))
}