-
Notifications
You must be signed in to change notification settings - Fork 8
HYPERFLEET-363 | feat(logger): Integrate database logging with LOG_LEVEL and fix mixed output format #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
openshift-merge-bot
merged 1 commit into
openshift-hyperfleet:main
from
yasun1:slog-fix
Jan 14, 2026
+386
−39
Merged
HYPERFLEET-363 | feat(logger): Integrate database logging with LOG_LEVEL and fix mixed output format #35
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -67,6 +67,10 @@ export MASKING_HEADERS="Authorization,Cookie,X-API-Key" | |
|
|
||
| # JSON body fields to mask (comma-separated) | ||
| export MASKING_FIELDS="password,token,secret,api_key" | ||
|
|
||
| # Database debug mode (true/false) | ||
| # When true, logs all SQL queries regardless of LOG_LEVEL | ||
| export DB_DEBUG=false | ||
| ``` | ||
|
|
||
| ### Configuration Struct | ||
|
|
@@ -251,6 +255,97 @@ export LOG_LEVEL=info | |
|
|
||
| No code changes required - the logger automatically adapts output format based on configuration. | ||
|
|
||
| ## Database Logging | ||
|
|
||
| HyperFleet API automatically integrates database (GORM) logging with the application's `LOG_LEVEL` configuration while providing a `DB_DEBUG` override for database-specific debugging. | ||
|
|
||
| ### LOG_LEVEL Integration | ||
|
|
||
| Database logs follow the application log level by default: | ||
|
|
||
| | LOG_LEVEL | GORM Behavior | What Gets Logged | | ||
| |-----------|---------------|------------------| | ||
| | `debug` | Info level | All SQL queries with parameters, duration, and row counts | | ||
| | `info` | Warn level | Only slow queries (>200ms) and errors | | ||
| | `warn` | Warn level | Only slow queries (>200ms) and errors | | ||
| | `error` | Silent | Nothing (database logging disabled) | | ||
|
|
||
| ### DB_DEBUG Override | ||
|
|
||
| The `DB_DEBUG` environment variable provides database-specific debugging without changing the global `LOG_LEVEL`: | ||
|
|
||
| ```bash | ||
| # Production environment with database debugging | ||
| export LOG_LEVEL=info # Application logs remain at INFO | ||
| export LOG_FORMAT=json # Production format | ||
| export DB_DEBUG=true # Force all SQL queries to be logged | ||
| ./bin/hyperfleet-api serve | ||
| ``` | ||
|
|
||
| **Priority:** | ||
| 1. If `DB_DEBUG=true`, all SQL queries are logged (GORM Info level) | ||
| 2. Otherwise, follow `LOG_LEVEL` mapping (see table above) | ||
|
|
||
| ### Database Log Examples | ||
|
|
||
| **Fast query (LOG_LEVEL=debug or DB_DEBUG=true):** | ||
|
|
||
| JSON format: | ||
| ```json | ||
| { | ||
| "timestamp": "2026-01-14T11:31:29.788683+08:00", | ||
| "level": "info", | ||
| "message": "GORM query", | ||
| "duration_ms": 9.052167, | ||
| "rows": 1, | ||
| "sql": "INSERT INTO \"clusters\" (\"id\",\"created_time\",...) VALUES (...)", | ||
| "component": "api", | ||
| "version": "0120ac6-modified", | ||
| "hostname": "yasun-mac", | ||
| "request_id": "38EOuujxBDUduP0hYLxVGMm69Dq", | ||
| "transaction_id": 1157 | ||
| } | ||
| ``` | ||
|
|
||
| Text format: | ||
| ```text | ||
| 2026-01-14T11:34:23+08:00 INFO [api] [0120ac6-modified] [yasun-mac] GORM query request_id=38EPGnassU9SLNZ82XiXZLiWS4i duration_ms=10.135875 rows=1 sql="INSERT INTO \"clusters\" (\"id\",\"created_time\",...) VALUES (...)" | ||
| ``` | ||
|
|
||
| **Slow query (>200ms, visible at all log levels except error):** | ||
|
|
||
| ```json | ||
| { | ||
| "timestamp": "2026-01-14T12:00:00Z", | ||
| "level": "warn", | ||
| "message": "GORM query", | ||
| "duration_ms": 250.5, | ||
| "rows": 1000, | ||
| "sql": "SELECT * FROM clusters WHERE ...", | ||
| "request_id": "...", | ||
| "transaction_id": 1234 | ||
| } | ||
| ``` | ||
|
|
||
| **Database error (visible at all log levels):** | ||
|
|
||
| ```json | ||
| { | ||
| "timestamp": "2026-01-14T12:00:00Z", | ||
| "level": "error", | ||
| "message": "GORM query error", | ||
| "error": "pq: duplicate key value violates unique constraint \"idx_clusters_name\"", | ||
| "duration_ms": 10.5, | ||
| "rows": 0, | ||
| "sql": "INSERT INTO \"clusters\" ...", | ||
| "request_id": "..." | ||
| } | ||
| ``` | ||
|
|
||
| ### Backward Compatibility | ||
|
|
||
| The existing `--enable-db-debug` CLI flag and `DB_DEBUG` environment variable continue to work exactly as before. The new functionality only adds automatic integration with `LOG_LEVEL` when `DB_DEBUG` is not explicitly set. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we keep and old config for backward compatibility? |
||
|
|
||
| ## Log Output Examples | ||
|
|
||
| ### Error Logs with Stack Traces | ||
|
|
@@ -354,6 +449,8 @@ env().Config.Logging.Masking.Fields = append( | |
|
|
||
| ## Best Practices | ||
|
|
||
| ### Application Logging | ||
|
|
||
| 1. **Always use context**: `logger.Info(ctx, "msg")` not `slog.Info("msg")` | ||
| 2. **Use WithError for errors**: `logger.WithError(ctx, err).Error(...)` not `"error", err` | ||
| 3. **Use field constants**: `logger.FieldEnvironment` not `"environment"` | ||
|
|
@@ -362,6 +459,15 @@ env().Config.Logging.Masking.Fields = append( | |
| 6. **Never log sensitive data**: Always sanitize passwords, tokens, connection strings | ||
| 7. **Choose appropriate levels**: DEBUG (dev), INFO (normal), WARN (client error), ERROR (server error) | ||
|
|
||
| ### Database Logging | ||
|
|
||
| 1. **Use LOG_LEVEL for database logs**: Don't set `DB_DEBUG` unless specifically debugging database issues | ||
| 2. **Production default**: `LOG_LEVEL=info` hides fast queries, shows slow queries (>200ms) | ||
| 3. **Temporary debugging**: Use `DB_DEBUG=true` for production database troubleshooting, then disable it | ||
| 4. **Development**: Use `LOG_LEVEL=debug` to see all SQL queries during development | ||
| 5. **High-traffic systems**: Consider `LOG_LEVEL=warn` to minimize database log volume | ||
| 6. **Monitor slow queries**: Review WARN-level GORM logs for queries exceeding 200ms threshold | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Logs Not Appearing | ||
|
|
@@ -392,6 +498,31 @@ mainRouter.Use(logging.RequestLoggingMiddleware) | |
| 2. Verify field names match configuration (case-insensitive) | ||
| 3. Check JSON structure: Masking only works on top-level fields | ||
|
|
||
| ### SQL Queries Not Appearing | ||
|
|
||
| 1. Check log level: `export LOG_LEVEL=debug` (to see all SQL queries) | ||
| 2. Check DB_DEBUG: `export DB_DEBUG=true` (to force SQL logging at any log level) | ||
| 3. Verify queries are executing: Check if API operations complete successfully | ||
| 4. Check log format: Use `LOG_FORMAT=text` for easier debugging | ||
|
|
||
| ### Too Many SQL Queries in Logs | ||
|
|
||
| 1. Production mode: `export LOG_LEVEL=info` (hides fast queries < 200ms) | ||
| 2. Disable DB_DEBUG: `export DB_DEBUG=false` or unset it | ||
| 3. Minimal mode: `export LOG_LEVEL=warn` (only slow queries and errors) | ||
| 4. Silent mode: `export LOG_LEVEL=error` (no SQL queries logged) | ||
|
|
||
| ### Only Want to See Slow Queries | ||
|
|
||
| Use production default configuration: | ||
| ```bash | ||
| export LOG_LEVEL=info | ||
| export LOG_FORMAT=json | ||
| export DB_DEBUG=false # or leave unset | ||
| ``` | ||
|
|
||
| This will only log SQL queries that take longer than 200ms. | ||
|
|
||
| ## Testing | ||
|
|
||
| ### Unit Tests | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,18 @@ | ||
| package db_session | ||
|
|
||
| import "sync" | ||
| import ( | ||
| "sync" | ||
|
|
||
| "gorm.io/gorm/logger" | ||
| ) | ||
|
|
||
| const ( | ||
| disable = "disable" | ||
| ) | ||
|
|
||
| var once sync.Once | ||
|
|
||
| // LoggerReconfigurable allows runtime reconfiguration of the database logger | ||
| type LoggerReconfigurable interface { | ||
| ReconfigureLogger(level logger.LogLevel) | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: openshift-hyperfleet/hyperfleet-api
Length of output: 106
🏁 Script executed:
Repository: openshift-hyperfleet/hyperfleet-api
Length of output: 2879
🏁 Script executed:
Repository: openshift-hyperfleet/hyperfleet-api
Length of output: 5272
🏁 Script executed:
sed -n '293,343p' docs/logging.mdRepository: openshift-hyperfleet/hyperfleet-api
Length of output: 1372
Update slow query example to match actual GORM logger output.
The slow query example shows incorrect message and is missing a field:
"GORM slow query"(not"GORM query") — see line 72 ofpkg/logger/gorm_logger.go"threshold_ms"field that is emitted at line 69Corrected slow query example
{ "timestamp": "2026-01-14T12:00:00Z", "level": "warn", "message": "GORM slow query", "duration_ms": 250.5, "threshold_ms": 200.0, "rows": 1000, "sql": "SELECT * FROM clusters WHERE ...", "request_id": "...", "transaction_id": 1234 }🤖 Prompt for AI Agents