Skip to content

Conversation

@pantelm
Copy link

@pantelm pantelm commented Nov 16, 2025

I use openhue-cli inside a script for polybar and I have lots of accessories that are not lights so the log is growing to much.

With this simple change, the user can choose the log level he want from the config file
Log levels are strings from Logrus

Summary by CodeRabbit

  • New Features
    • Added configurable log level support — the app now reads and applies a user-specified logging verbosity at startup.
  • Bug Fixes
    • Logging now respects the configured level instead of using a fixed default; invalid log level values will cause startup to fail so issues are surfaced immediately.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 16, 2025

Walkthrough

Config gains a new LogLevel field and the logger Init function now accepts and applies a log level from configuration; logger initialization reads and parses that level and sets the logger accordingly, fatalling on parse error.

Changes

Cohort / File(s) Summary
Configuration & Logger
openhue/config.go, util/logger/logger.go
Added LogLevel string to Config; changed Init(path string)Init(path string, level string); logger now parses level with log.ParseLevel and sets log.SetLevel(logLevel); parse errors call log.Fatal(err).

Sequence Diagram

sequenceDiagram
    participant Config
    participant Logger as Logger.Init
    participant LogLib as log package

    Config->>Config: load config file
    Config->>Config: read `LogLevel`
    Config->>Logger: Init(path, LogLevel)
    alt parse succeeds
        Logger->>LogLib: ParseLevel(level)
        Logger->>LogLib: SetLevel(parsedLevel)
        Logger->>LogLib: SetOutput(file)
    else parse fails
        Logger->>Logger: Fatal(error)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Check callers of util/logger.Init for updated signature usage.
  • Confirm fatal-on-parse behavior is intentional (unreachable assignment after log.Fatal).
  • Verify tests or startup paths handle missing/invalid LogLevel values and that defaulting behavior (if desired) is handled elsewhere.

Poem

🐇 In burrows of code I hop and peep,

I tweak the logs so wakes not sleep.
A level added, crisp and bright,
Now bunnies whisper or roar by night. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: allowing users to set the log level from the configuration file, which is the primary objective of the PR.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6f76573 and f058751.

📒 Files selected for processing (1)
  • util/logger/logger.go (1 hunks)
🔇 Additional comments (1)
util/logger/logger.go (1)

8-8: Function signature updated to accept log level parameter.

The addition of the level parameter enables configurable log levels from the configuration file, which aligns well with the PR objectives.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
openhue/config.go (1)

76-77: Consider persisting LogLevel in the config file.

The Save() function currently only persists Bridge and Key but not LogLevel. If users need to set the log level programmatically (e.g., via a setup command), it won't be saved to the configuration file.

If this is intentional (log level only set via manual config editing), this can be ignored. Otherwise, apply this diff:

 	viper.Set("Bridge", c.Bridge)
 	viper.Set("Key", c.Key)
+	if c.LogLevel != "" {
+		viper.Set("log_level", c.LogLevel)
+	}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 262260d and 6f76573.

📒 Files selected for processing (2)
  • openhue/config.go (2 hunks)
  • util/logger/logger.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
openhue/config.go (1)
util/logger/logger.go (1)
  • Init (8-26)

Comment on lines +62 to +63
c.LogLevel = viper.GetString("log_level")
logger.Init(filepath.Join(configPath, "openhue.log"), c.LogLevel)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Consider providing a default log level.

If log_level is not present in the config file, viper.GetString returns an empty string, which will cause log.ParseLevel in logger.Init to fail and terminate the application. Consider setting a sensible default (e.g., "info") to prevent fatal errors when the field is missing.

Apply this diff to add a default log level:

 	c.Bridge = viper.GetString("Bridge")
 	c.Key = viper.GetString("Key")
 	c.LogLevel = viper.GetString("log_level")
+	if c.LogLevel == "" {
+		c.LogLevel = "info"
+	}
 	logger.Init(filepath.Join(configPath, "openhue.log"), c.LogLevel)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
c.LogLevel = viper.GetString("log_level")
logger.Init(filepath.Join(configPath, "openhue.log"), c.LogLevel)
c.Bridge = viper.GetString("Bridge")
c.Key = viper.GetString("Key")
c.LogLevel = viper.GetString("log_level")
if c.LogLevel == "" {
c.LogLevel = "info"
}
logger.Init(filepath.Join(configPath, "openhue.log"), c.LogLevel)
🤖 Prompt for AI Agents
In openhue/config.go around lines 62-63, the code reads c.LogLevel =
viper.GetString("log_level") and passes it to logger.Init which will fail if the
config key is missing; change this to provide a sensible default (e.g., "info")
by either calling viper.SetDefault("log_level", "info") before reading, or by
checking the returned string and falling back: c.LogLevel =
viper.GetString("log_level"); if c.LogLevel == "" { c.LogLevel = "info" } and
then call logger.Init with that value.

Comment on lines 16 to 21
logLevel, err := log.ParseLevel(level)
if err != nil {
log.Fatal(err)
level = log.InfoLevel.String()
}
log.SetLevel(logLevel)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

Verify behavior when level is an empty string.

If the LogLevel field is not set in the config file, an empty string will be passed to log.ParseLevel. This could cause the application to terminate with a fatal error.

Run the following script to check how logrus handles empty string parsing:


🏁 Script executed:

#!/bin/bash
# Description: Check logrus ParseLevel behavior with empty string

cat > /tmp/test_loglevel.go << 'EOF'
package main

import (
	"fmt"
	log "github.com/sirupsen/logrus"
)

func main() {
	// Test empty string
	level, err := log.ParseLevel("")
	if err != nil {
		fmt.Printf("Empty string error: %v\n", err)
	} else {
		fmt.Printf("Empty string parsed as: %v\n", level)
	}
	
	// Test valid levels
	for _, l := range []string{"trace", "debug", "info", "warn", "error", "fatal", "panic"} {
		level, err := log.ParseLevel(l)
		if err != nil {
			fmt.Printf("%s error: %v\n", l, err)
		} else {
			fmt.Printf("%s parsed as: %v\n", l, level)
		}
	}
}
EOF

cd /tmp
go mod init test 2>/dev/null || true
go get github.com/sirupsen/[email protected]
go run test_loglevel.go

Length of output: 635


I need to gather more information about how logrus handles empty strings in ParseLevel. Let me search for this and also examine the codebase context.

Now let me examine the codebase to understand the actual context of this logger code:



🏁 Script executed:

#!/bin/bash
# Find and examine the logger file to understand context
fd -t f logger.go | head -20

Length of output: 21


🏁 Script executed:

#!/bin/bash
# Look for the specific file mentioned in the review
find . -name "logger.go" -path "*/util/logger/*" 2>/dev/null

Length of output: 23


🏁 Script executed:

#!/bin/bash
# Search for the code snippet in the review to find the exact context
rg -n "logLevel, err := log.ParseLevel" --type=go -B5 -A10

Length of output: 763


🏁 Script executed:

#!/bin/bash
# Check if there's config loading and how empty strings are handled
rg -n "LogLevel" --type=go -B2 -A2 | head -50

Length of output: 481


🏁 Script executed:

#!/bin/bash
# Look for yaml/config tag handling to understand field initialization
rg -n "yaml\|toml\|json" --type=go -B1 -A1 | grep -i "loglevel\|log.level" -B2 -A2

Length of output: 0


Fix unreachable fallback logic and handle empty log level gracefully.

The issue is valid and critical for startup reliability. When the log_level config key is not set, viper.GetString("log_level") returns an empty string, which is passed to log.ParseLevel(). This causes the function to fail and call log.Fatal(err), terminating the application. The reassignment on line 19 (level = log.InfoLevel.String()) is unreachable dead code.

To fix this:

  • Check if level is empty before parsing, and set a sensible default (e.g., info)
  • Or move the reassignment before log.Fatal() so it executes if parsing fails

Example:

logLevel, err := log.ParseLevel(level)
if err != nil {
    level = log.InfoLevel.String()
    logLevel, _ = log.ParseLevel(level)
}
log.SetLevel(logLevel)
🤖 Prompt for AI Agents
In util/logger/logger.go around lines 16 to 21, the current logic calls
log.ParseLevel on a possibly empty string and then log.Fatal on error, making
the fallback assignment unreachable; change it so you first set a sensible
default when the config value is empty (e.g., "info"), then parse, and if
ParseLevel still returns an error do not call log.Fatal but fall back to info by
reassigning level and reparsing (or directly set log.InfoLevel) before calling
log.SetLevel; ensure no unreachable code remains and the application does not
exit on a bad or empty log level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant