Skip to content

Add custom order support for console encode #1496

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

halfcrazy
Copy link

@halfcrazy halfcrazy commented Apr 17, 2025

fix
#1031
#499
#388 (comment)

Summary by CodeRabbit

  • New Features
    • Added support for customizable ordering of log entry fields in console output. Users can configure the sequence of fields such as time, level, logger name, caller, function, message, and stack trace.
  • Bug Fixes
    • Improved formatting and handling of log output, especially with context fields and stack traces.
  • Tests
    • Introduced comprehensive tests to verify field ordering, formatting, separator handling, and behavior with missing fields in console logs.

@CLAassistant
Copy link

CLAassistant commented Apr 17, 2025

CLA assistant check
All committers have signed the CLA.

Copy link

coderabbitai bot commented Apr 17, 2025

Walkthrough

The changes introduce a configurable and ordered field output for the console encoder in the logging system. A new OrderField type and associated constants define possible log entry fields, and a ConsoleFieldOrder slice in the encoder configuration allows users to specify the desired output order. The console encoder's logic is refactored to iterate over this order when formatting log entries, handling message and context fields with improved formatting and type-aware buffer writes. Extensive tests are added to verify field ordering, formatting, separator handling, and behavior with missing fields. The JSON encoder ensures a default order is set if not specified or mismatched.

Changes

File(s) Change Summary
zapcore/console_encoder.go Refactored console encoder to support configurable, ordered output via OrderField and ConsoleFieldOrder. Improved message/context formatting and buffer writes. Adjusted NewConsoleEncoder and Clone methods.
zapcore/encoder.go Added ConsoleFieldOrder []OrderField field to EncoderConfig for field order configuration.
zapcore/json_encoder.go Ensured ConsoleFieldOrder is initialized to a default order in newJSONEncoder if not set or length mismatched.
zapcore/console_encoder_test.go Added comprehensive tests for field ordering, formatting, separators, context fields, and missing field scenarios in the console encoder.

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant ConsoleEncoder
    participant Buffer
    participant JSONEncoder

    App->>ConsoleEncoder: EncodeEntry(entry, fields)
    ConsoleEncoder->>ConsoleEncoder: Iterate ConsoleFieldOrder
    alt Field is Message
        ConsoleEncoder->>Buffer: Append raw message
        ConsoleEncoder->>JSONEncoder: Encode context fields as JSON
        JSONEncoder-->>ConsoleEncoder: JSON context string
        ConsoleEncoder->>Buffer: Append context JSON
    else Field is Stack
        ConsoleEncoder->>Buffer: Append stack trace (with newline if set)
    else Other Fields
        ConsoleEncoder->>Buffer: Append field value
    end
    ConsoleEncoder-->>App: Return formatted Buffer
Loading

Poem

🐇
In the warren of logs, we hop with delight,
Fields in new order, each shining bright.
Messages and context, neatly in line,
Stack traces leap in, right on time.
With tests all around and buffers that gleam,
Our logging now dances—a rabbit’s dream!

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@halfcrazy halfcrazy force-pushed the feat-console-order branch from 8ee21f7 to f7cc1ba Compare April 17, 2025 10:46
Copy link

@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: 2

🧹 Nitpick comments (5)
zapcore/encoder.go (1)

359-360: Typo & wording – “filed” → “field”

The comment reads “Configures the console filed order”.
Spelling should be “field”, and adding an article clarifies the intent.

- // Configures the console filed order. Defaults to Time Level Name Callee Function Message Stack
+ // Configures the console **field** order. Defaults to Time Level Name Callee Function Message Stack
zapcore/console_encoder.go (3)

37-47: Exported identifiers need package‑doc comments

OrderField and the associated constants are exported but undocumented, which triggers revive and hampers godoc usability. Add a short comment block explaining the purpose and allowed values.

Example:

// OrderField represents one of the logical parts of a log entry that can be
// arranged by ConsoleFieldOrder.
type OrderField string
🧰 Tools
🪛 golangci-lint (1.64.8)

[warning] 37-37: exported: exported type OrderField should have comment or be unexported

(revive)


[warning] 40-40: exported: exported const OrderFieldTime should have comment (or a comment on this block) or be unexported

(revive)


103-169: Potential memory churn – cloning a JSON encoder per entry

Inside OrderFieldMessage a new JSON encoder is cloned every time an entry is logged merely to encode the context. For high‑volume logging this is a noticeable allocation hotspot.

Consider re‑using a scratch encoder from a sync.Pool, or extending sliceArrayEncoder to accept key/value pairs directly, eliminating the clone altogether.
This is an optimisation suggestion; correctness is unaffected.


213-239: Dead code – writeContext and addSeparatorIfNecessary

After the refactor EncodeEntry no longer calls writeContext; consequently both writeContext and its helper are now unused.

Consider removing them to keep the codebase clean and to silence dead‑code linters.

🧰 Tools
🪛 golangci-lint (1.64.8)

213-213: func consoleEncoder.writeContext is unused

(unused)


234-234: func consoleEncoder.addSeparatorIfNecessary is unused

(unused)

zapcore/console_encoder_test.go (1)

131-135: Formatting nits picked up by gofumpt

golangci-lint flags several “file is not properly formatted” warnings.
Running gofumpt -w zapcore/console_encoder_test.go will auto‑fix spacing and import grouping without altering logic.
Keeping tests formatted improves diff readability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d48253 and f7cc1ba.

📒 Files selected for processing (4)
  • zapcore/console_encoder.go (3 hunks)
  • zapcore/console_encoder_test.go (1 hunks)
  • zapcore/encoder.go (1 hunks)
  • zapcore/json_encoder.go (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
zapcore/encoder.go (1)
zapcore/console_encoder.go (1)
  • OrderField (37-37)
zapcore/console_encoder_test.go (5)
zapcore/console_encoder.go (9)
  • OrderField (37-37)
  • OrderFieldTime (40-40)
  • OrderFieldLevel (41-41)
  • OrderFieldName (42-42)
  • OrderFieldCallee (43-43)
  • OrderFieldFunction (44-44)
  • OrderFieldMessage (45-45)
  • OrderFieldStack (46-46)
  • NewConsoleEncoder (73-84)
field.go (2)
  • String (222-224)
  • Time (347-352)
zapcore/encoder.go (1)
  • EncoderConfig (331-361)
zapcore/field.go (1)
  • StringType (67-67)
zapcore/entry.go (2)
  • Entry (143-150)
  • EntryCaller (70-76)
zapcore/console_encoder.go (2)
zapcore/encoder.go (2)
  • Encoder (457-468)
  • FullNameEncoder (313-315)
field.go (3)
  • Time (347-352)
  • String (222-224)
  • Stack (367-369)
🪛 golangci-lint (1.64.8)
zapcore/console_encoder_test.go

145-145: File is not properly formatted

(gofumpt)


223-223: File is not properly formatted

(gofumpt)


248-248: File is not properly formatted

(gofumpt)


276-276: File is not properly formatted

(gofumpt)


281-281: File is not properly formatted

(gofumpt)


286-286: File is not properly formatted

(gofumpt)


330-330: File is not properly formatted

(gofumpt)


342-342: File is not properly formatted

(gofumpt)


354-354: File is not properly formatted

(gofumpt)

zapcore/console_encoder.go

[warning] 37-37: exported: exported type OrderField should have comment or be unexported

(revive)


[warning] 40-40: exported: exported const OrderFieldTime should have comment (or a comment on this block) or be unexported

(revive)


49-49: File is not properly formatted

(gofumpt)

Comment on lines 93 to 95
if cfg.ConsoleFieldOrder == nil {
cfg.ConsoleFieldOrder = defaultConsoleOrder
}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Prevent silent mis‑configuration when order slice is non‑nil but empty

ConsoleFieldOrder == nil is caught, but an empty slice (len == 0) still bypasses the default and later causes the encoder to emit nothing. Guard both cases:

-if cfg.ConsoleFieldOrder == nil {
+if len(cfg.ConsoleFieldOrder) == 0 {
     cfg.ConsoleFieldOrder = defaultConsoleOrder
 }

To verify that switching to a len(...) == 0 check safely covers both nil and empty slices across the codebase, let’s locate where ConsoleFieldOrder and defaultConsoleOrder are defined and referenced:


🏁 Script executed:

#!/bin/bash
# Find the definition and usage of ConsoleFieldOrder in the JSON encoder:
rg "ConsoleFieldOrder" -n zapcore/json_encoder.go

# Locate where defaultConsoleOrder is declared:
rg "defaultConsoleOrder" -n zapcore/json_encoder.go

# Check other references to ConsoleFieldOrder across the repo:
rg "ConsoleFieldOrder" -n .

Length of output: 1051


Guard against empty ConsoleFieldOrder slices

In zapcore/json_encoder.go (lines 93–95), the current nil‑only check lets an explicitly empty slice slip through and causes the encoder to emit nothing. Update the guard to cover both nil and empty slices:

-   if cfg.ConsoleFieldOrder == nil {
+   if len(cfg.ConsoleFieldOrder) == 0 {
        cfg.ConsoleFieldOrder = defaultConsoleOrder
    }

Without this change, setting cfg.ConsoleFieldOrder = []OrderField{} silently disables all fields.
You may also want to add a test in zapcore/console_encoder_test.go that verifies an empty slice falls back to defaultConsoleOrder.

@halfcrazy halfcrazy force-pushed the feat-console-order branch from f7cc1ba to 0953d90 Compare April 17, 2025 11:55
Copy link

@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: 0

♻️ Duplicate comments (1)
zapcore/console_encoder.go (1)

192-195: ⚠️ Potential issue

Fix type assertions to avoid runtime panics

The current type assertions e.(int64) and e.(uint64) will panic if the matched element is not exactly of that type (e.g., when it's an int32). This is a critical issue as this branch will be hit for numeric timestamps and counters.

Replace the type assertions with individual handling for each numeric type:

-		case int, int8, int16, int32, int64:
-			line.AppendInt(int64(e.(int64)))
-		case uint, uint8, uint16, uint32, uint64:
-			line.AppendUint(uint64(e.(uint64)))
+		case int:
+			line.AppendInt(int64(e))
+		case int8:
+			line.AppendInt(int64(e))
+		case int16:
+			line.AppendInt(int64(e))
+		case int32:
+			line.AppendInt(int64(e))
+		case int64:
+			line.AppendInt(e)
+		case uint:
+			line.AppendUint(uint64(e))
+		case uint8:
+			line.AppendUint(uint64(e))
+		case uint16:
+			line.AppendUint(uint64(e))
+		case uint32:
+			line.AppendUint(uint64(e))
+		case uint64:
+			line.AppendUint(e)
🧹 Nitpick comments (7)
zapcore/console_encoder.go (3)

37-47: Add documentation for exported type and constants

The exported type OrderField and its constants (OrderFieldTime, OrderFieldLevel, etc.) should have proper documentation comments explaining their purpose and usage, which is to specify the order of fields in the console encoder output.

+// OrderField represents a field that can be included in console encoder output.
 type OrderField string

+// Console encoder field constants that can be used to configure field order.
 const (
+	// OrderFieldTime represents the timestamp field
 	OrderFieldTime     OrderField = "Time"
+	// OrderFieldLevel represents the log level field
 	OrderFieldLevel    OrderField = "Level"
+	// OrderFieldName represents the logger name field
 	OrderFieldName     OrderField = "Name"
+	// OrderFieldCallee represents the caller file and line field
 	OrderFieldCallee   OrderField = "Callee"
+	// OrderFieldFunction represents the caller function field
 	OrderFieldFunction OrderField = "Function"
+	// OrderFieldMessage represents the log message field
 	OrderFieldMessage  OrderField = "Message"
+	// OrderFieldStack represents the stack trace field
 	OrderFieldStack    OrderField = "Stack"
 )
🧰 Tools
🪛 golangci-lint (1.64.8)

[warning] 37-37: exported: exported type OrderField should have comment or be unexported

(revive)


[warning] 40-40: exported: exported const OrderFieldTime should have comment (or a comment on this block) or be unexported

(revive)


49-50: Format consistent with Go style

The variable declaration is split across lines in a way that doesn't conform to Go formatting standards.

-var defaultConsoleOrder = []OrderField{OrderFieldTime, OrderFieldLevel, OrderFieldName, OrderFieldCallee,
-	OrderFieldFunction, OrderFieldMessage, OrderFieldStack}
+var defaultConsoleOrder = []OrderField{
+	OrderFieldTime,
+	OrderFieldLevel,
+	OrderFieldName,
+	OrderFieldCallee,
+	OrderFieldFunction,
+	OrderFieldMessage,
+	OrderFieldStack,
+}
🧰 Tools
🪛 golangci-lint (1.64.8)

49-49: File is not properly formatted

(gofumpt)


156-160: Consider more efficient string handling for context fields

The current implementation converts the context buffer to a string, adds curly braces, and then appends it as a string. This creates multiple string allocations. Consider using direct buffer operations instead.

 			// Check if the cloned encoder has any content.
 			if contextEncoder.buf.Len() > 0 {
-				// Manually add curly braces because the buffer contains only the inner KVs.
-				jsonStr := "{" + contextEncoder.buf.String() + "}"
-				arr.AppendString(jsonStr)
+				// Add context as JSON directly to array
+				arr.AppendString("{")
+				arr.AppendString(contextEncoder.buf.String())
+				arr.AppendString("}")
 			}

Or alternatively, for even better performance with no intermediate string allocations:

 			if contextEncoder.buf.Len() > 0 {
-				// Manually add curly braces because the buffer contains only the inner KVs.
-				jsonStr := "{" + contextEncoder.buf.String() + "}"
-				arr.AppendString(jsonStr)
+				// Use a temporary buffer to construct the JSON context
+				contextBuf := bufferpool.Get()
+				defer contextBuf.Free()
+				contextBuf.AppendByte('{')
+				contextBuf.Write(contextEncoder.buf.Bytes())
+				contextBuf.AppendByte('}')
+				arr.AppendString(contextBuf.String())
 			}
zapcore/console_encoder_test.go (4)

145-147: Format list elements consistently

This list would be more readable with each element on its own line, following Go style guidelines.

-			order: []OrderField{OrderFieldTime, OrderFieldLevel, OrderFieldName, OrderFieldCallee,
-				OrderFieldFunction, OrderFieldMessage, OrderFieldStack},
+			order: []OrderField{
+				OrderFieldTime,
+				OrderFieldLevel,
+				OrderFieldName,
+				OrderFieldCallee,
+				OrderFieldFunction,
+				OrderFieldMessage,
+				OrderFieldStack,
+			},
🧰 Tools
🪛 golangci-lint (1.64.8)

145-145: File is not properly formatted

(gofumpt)


223-225: Apply consistent formatting to all field order slices

Throughout the test file, there are several multiline field order declarations that could benefit from consistent formatting for improved readability.

The formatting suggestion provided for the first slice at lines 145-147 should be consistently applied to all similar slice declarations in the test file. For example, the slice at lines 330-332 should be formatted as:

-			order: []OrderField{OrderFieldTime, OrderFieldLevel, OrderFieldName, OrderFieldCallee,
-				OrderFieldFunction, OrderFieldMessage, OrderFieldStack},
+			order: []OrderField{
+				OrderFieldTime,
+				OrderFieldLevel,
+				OrderFieldName,
+				OrderFieldCallee,
+				OrderFieldFunction,
+				OrderFieldMessage,
+				OrderFieldStack,
+			},

Also applies to: 276-278, 281-283, 286-288, 330-332, 342-344, 354-356

🧰 Tools
🪛 golangci-lint (1.64.8)

223-223: File is not properly formatted

(gofumpt)


248-248: Simplify field creation syntax

The Field initialization could be simplified by removing the redundant Field type specification.

-			fields := []Field{Field{Key: "foo", Type: StringType, String: "bar"}}
+			fields := []Field{{Key: "foo", Type: StringType, String: "bar"}}
🧰 Tools
🪛 golangci-lint (1.64.8)

248-248: File is not properly formatted

(gofumpt)


303-305: Remove commented-out test assertions

Lines 304-305 contain commented-out assertions. These should either be uncommented if necessary or removed completely to maintain clean test code.

-			// Can't assert exact output easily due to field order and separator variations
-			// assert.Contains(t, buf.String(), sep, "Separator not found in output")
-			// No longer check format, as different console encoder versions might behave differently.
+			// Note: Exact output verification is challenging due to field order and separator variations
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f7cc1ba and 0953d90.

📒 Files selected for processing (4)
  • zapcore/console_encoder.go (3 hunks)
  • zapcore/console_encoder_test.go (1 hunks)
  • zapcore/encoder.go (1 hunks)
  • zapcore/json_encoder.go (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • zapcore/encoder.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • zapcore/json_encoder.go
🧰 Additional context used
🧬 Code Graph Analysis (2)
zapcore/console_encoder.go (2)
zapcore/encoder.go (2)
  • Encoder (457-468)
  • FullNameEncoder (313-315)
field.go (3)
  • Time (347-352)
  • String (222-224)
  • Stack (367-369)
zapcore/console_encoder_test.go (5)
zapcore/console_encoder.go (9)
  • OrderField (37-37)
  • OrderFieldTime (40-40)
  • OrderFieldLevel (41-41)
  • OrderFieldName (42-42)
  • OrderFieldCallee (43-43)
  • OrderFieldFunction (44-44)
  • OrderFieldMessage (45-45)
  • OrderFieldStack (46-46)
  • NewConsoleEncoder (73-84)
field.go (2)
  • String (222-224)
  • Time (347-352)
zapcore/encoder.go (1)
  • EncoderConfig (331-361)
zapcore/field.go (1)
  • StringType (67-67)
zapcore/entry.go (2)
  • Entry (143-150)
  • EntryCaller (70-76)
🪛 golangci-lint (1.64.8)
zapcore/console_encoder.go

[warning] 37-37: exported: exported type OrderField should have comment or be unexported

(revive)


[warning] 40-40: exported: exported const OrderFieldTime should have comment (or a comment on this block) or be unexported

(revive)


49-49: File is not properly formatted

(gofumpt)

zapcore/console_encoder_test.go

145-145: File is not properly formatted

(gofumpt)


223-223: File is not properly formatted

(gofumpt)


248-248: File is not properly formatted

(gofumpt)


276-276: File is not properly formatted

(gofumpt)


281-281: File is not properly formatted

(gofumpt)


286-286: File is not properly formatted

(gofumpt)


330-330: File is not properly formatted

(gofumpt)


342-342: File is not properly formatted

(gofumpt)


354-354: File is not properly formatted

(gofumpt)

🔇 Additional comments (1)
zapcore/console_encoder_test.go (1)

137-418: Great comprehensive test coverage

The test suite thoroughly covers critical aspects of the field ordering feature:

  • Different permutations of field orders
  • Context field handling with various field orders
  • Different separator strings
  • Missing field scenarios

This comprehensive approach ensures the feature works as expected in various scenarios. The debug information in the tests will also be helpful for diagnosing any future issues.

🧰 Tools
🪛 golangci-lint (1.64.8)

145-145: File is not properly formatted

(gofumpt)


223-223: File is not properly formatted

(gofumpt)


248-248: File is not properly formatted

(gofumpt)


276-276: File is not properly formatted

(gofumpt)


281-281: File is not properly formatted

(gofumpt)


286-286: File is not properly formatted

(gofumpt)


330-330: File is not properly formatted

(gofumpt)


342-342: File is not properly formatted

(gofumpt)


354-354: File is not properly formatted

(gofumpt)

@halfcrazy halfcrazy force-pushed the feat-console-order branch from 0953d90 to 8329c71 Compare April 17, 2025 12:02
Copy link

@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: 0

🧹 Nitpick comments (5)
zapcore/console_encoder.go (2)

37-47: Add godoc comments for exported type and constants

The OrderField type and its associated constants are exported but lack documentation comments. Following Go best practices, all exported declarations should have comments that explain their purpose and usage.

+// OrderField defines the type for fields that can be ordered in console encoder output.
 type OrderField string

 const (
+	// OrderFieldTime represents the timestamp field in log entries.
 	OrderFieldTime     OrderField = "Time"
+	// OrderFieldLevel represents the log level field.
 	OrderFieldLevel    OrderField = "Level"
+	// OrderFieldName represents the logger name field.
 	OrderFieldName     OrderField = "Name"
+	// OrderFieldCallee represents the caller (file:line) field.
 	OrderFieldCallee   OrderField = "Callee"
+	// OrderFieldFunction represents the calling function name field.
 	OrderFieldFunction OrderField = "Function"
+	// OrderFieldMessage represents the log message field.
 	OrderFieldMessage  OrderField = "Message"
+	// OrderFieldStack represents the stack trace field.
 	OrderFieldStack    OrderField = "Stack"
 )
🧰 Tools
🪛 golangci-lint (1.64.8)

[warning] 37-37: exported: exported type OrderField should have comment or be unexported

(revive)


[warning] 40-40: exported: exported const OrderFieldTime should have comment (or a comment on this block) or be unexported

(revive)


49-50: Fix formatting of multi-line slice declaration

The declaration of defaultConsoleOrder spans multiple lines but doesn't follow Go formatting conventions. The slice elements should either all be on one line or each on its own line with proper indentation.

-var defaultConsoleOrder = []OrderField{OrderFieldTime, OrderFieldLevel, OrderFieldName, OrderFieldCallee,
-	OrderFieldFunction, OrderFieldMessage, OrderFieldStack}
+var defaultConsoleOrder = []OrderField{
+	OrderFieldTime,
+	OrderFieldLevel,
+	OrderFieldName,
+	OrderFieldCallee,
+	OrderFieldFunction,
+	OrderFieldMessage,
+	OrderFieldStack,
+}
🧰 Tools
🪛 golangci-lint (1.64.8)

49-49: File is not properly formatted

(gofumpt)

zapcore/console_encoder_test.go (3)

145-147: Fix multi-line slice formatting in test cases

Multiple test cases have slice initializers that span multiple lines without proper Go formatting. Similar to the issue in the main file, these should be properly formatted either as single-line or with each element on its own line.

For example:

-			order: []OrderField{OrderFieldTime, OrderFieldLevel, OrderFieldName, OrderFieldCallee,
-				OrderFieldFunction, OrderFieldMessage, OrderFieldStack},
+			order: []OrderField{
+				OrderFieldTime,
+				OrderFieldLevel,
+				OrderFieldName,
+				OrderFieldCallee,
+				OrderFieldFunction,
+				OrderFieldMessage,
+				OrderFieldStack,
+			},

This same pattern should be applied to all similar multi-line slice initializations throughout the test file.

Also applies to: 223-225, 276-278, 281-283, 286-288, 330-332, 342-344, 354-356

🧰 Tools
🪛 golangci-lint (1.64.8)

145-145: File is not properly formatted

(gofumpt)


248-249: Simplify Field creation

The test is creating a Field directly with struct initialization, but the codebase likely has helper functions for this purpose.

-			fields := []Field{Field{Key: "foo", Type: StringType, String: "bar"}}
+			fields := []Field{String("foo", "bar")}
🧰 Tools
🪛 golangci-lint (1.64.8)

248-248: File is not properly formatted

(gofumpt)


268-313: Add assertions to separator testing

This test currently logs output but doesn't make any assertions about the results. While exact output matching might be difficult, you could still verify certain properties of the output.

Consider adding basic assertions to verify that:

  1. The output contains the message
  2. The separator appears in the output
  3. The number of separators is appropriate for the fields present

For example:

// Count occurrences of the separator in the output
sepCount := strings.Count(consoleOut.String(), sep)
// Calculate expected separator count (fields - 1, accounting for missing fields)
expectedFields := countPresentFields(entry, o.order)
expectedSeps := expectedFields - 1
if expectedSeps > 0 {
    assert.Equal(t, expectedSeps, sepCount, "Unexpected number of separators")
}
assert.Contains(t, consoleOut.String(), entry.Message, "Output should contain the message")

You would need to implement a helper countPresentFields() function to determine how many fields are actually present in the output.

🧰 Tools
🪛 golangci-lint (1.64.8)

276-276: File is not properly formatted

(gofumpt)


281-281: File is not properly formatted

(gofumpt)


286-286: File is not properly formatted

(gofumpt)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0953d90 and 8329c71.

📒 Files selected for processing (4)
  • zapcore/console_encoder.go (3 hunks)
  • zapcore/console_encoder_test.go (1 hunks)
  • zapcore/encoder.go (1 hunks)
  • zapcore/json_encoder.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • zapcore/encoder.go
  • zapcore/json_encoder.go
🧰 Additional context used
🧬 Code Graph Analysis (1)
zapcore/console_encoder_test.go (5)
zapcore/console_encoder.go (9)
  • OrderField (37-37)
  • OrderFieldTime (40-40)
  • OrderFieldLevel (41-41)
  • OrderFieldName (42-42)
  • OrderFieldCallee (43-43)
  • OrderFieldFunction (44-44)
  • OrderFieldMessage (45-45)
  • OrderFieldStack (46-46)
  • NewConsoleEncoder (73-84)
field.go (2)
  • String (222-224)
  • Time (347-352)
zapcore/encoder.go (1)
  • EncoderConfig (331-361)
zapcore/field.go (1)
  • StringType (67-67)
zapcore/entry.go (2)
  • Entry (143-150)
  • EntryCaller (70-76)
🪛 golangci-lint (1.64.8)
zapcore/console_encoder.go

[warning] 37-37: exported: exported type OrderField should have comment or be unexported

(revive)


[warning] 40-40: exported: exported const OrderFieldTime should have comment (or a comment on this block) or be unexported

(revive)


49-49: File is not properly formatted

(gofumpt)

zapcore/console_encoder_test.go

145-145: File is not properly formatted

(gofumpt)


223-223: File is not properly formatted

(gofumpt)


248-248: File is not properly formatted

(gofumpt)


276-276: File is not properly formatted

(gofumpt)


281-281: File is not properly formatted

(gofumpt)


286-286: File is not properly formatted

(gofumpt)


330-330: File is not properly formatted

(gofumpt)


342-342: File is not properly formatted

(gofumpt)


354-354: File is not properly formatted

(gofumpt)

🔇 Additional comments (4)
zapcore/console_encoder.go (2)

103-167: Well-structured field handling based on configured order

The field processing approach is well-designed, iterating through the configured order and handling each field appropriately. This implementation successfully handles field ordering while maintaining proper type handling and formatting.


171-222: Properly fixed type assertion and optimized buffer handling

The buffer writing loop is well-optimized with proper type handling. This approach correctly handles each numeric type individually, avoiding the previous potential runtime panics from incorrect type assertions. The special handling of newline-prefixed stack traces is also a nice touch.

zapcore/console_encoder_test.go (2)

137-207: Thorough test coverage for field ordering functionality

The test cases provide excellent coverage of different field ordering scenarios, with clear expected outputs for each case. The debug output inclusion is also helpful for troubleshooting.

🧰 Tools
🪛 golangci-lint (1.64.8)

145-145: File is not properly formatted

(gofumpt)


315-418: Comprehensive testing of edge cases

The tests for missing fields are thorough and well-structured, covering important edge cases like zero time values, missing logger names, undefined callers, and empty stacks. This attention to edge cases is commendable.

🧰 Tools
🪛 golangci-lint (1.64.8)

330-330: File is not properly formatted

(gofumpt)


342-342: File is not properly formatted

(gofumpt)


354-354: File is not properly formatted

(gofumpt)

@halfcrazy halfcrazy force-pushed the feat-console-order branch from 8329c71 to 9997486 Compare April 17, 2025 12:11
Copy link

@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: 0

🧹 Nitpick comments (3)
zapcore/console_encoder_test.go (3)

248-248: Simplify field declaration by removing redundant type.

The field declaration can be simplified by removing the redundant type specification.

-			fields := []Field{Field{Key: "foo", Type: StringType, String: "bar"}}
+			fields := []Field{{Key: "foo", Type: StringType, String: "bar"}}
🧰 Tools
🪛 golangci-lint (1.64.8)

248-248: File is not properly formatted

(gofumpt)


268-311: Consider adding basic assertions to the separator test.

While exact output verification may be challenging with different separators and field orders, consider adding some basic assertions to verify that the output contains the expected fields in some form, rather than just logging the output.

You could add assertions that check for the presence of specific fields in the output, such as:

// Example assertion to check if all fields are present
output := consoleOut.String()
assert.Contains(t, output, "hello")
assert.Contains(t, output, "info")
assert.Contains(t, output, sep) // Check separator is used
🧰 Tools
🪛 golangci-lint (1.64.8)

276-276: File is not properly formatted

(gofumpt)


281-281: File is not properly formatted

(gofumpt)


286-286: File is not properly formatted

(gofumpt)


145-147: Fix formatting of multiline slices according to gofumpt.

The static analysis tool golangci-lint (gofumpt) indicates formatting issues with these multiline slice literals. According to Go formatting conventions, all elements in a multiline slice literal should be indented consistently.

For example, apply this change to properly format these multiline slices:

-			order: []OrderField{OrderFieldTime, OrderFieldLevel, OrderFieldName, OrderFieldCallee,
-				OrderFieldFunction, OrderFieldMessage, OrderFieldStack},
+			order: []OrderField{
+				OrderFieldTime, OrderFieldLevel, OrderFieldName, OrderFieldCallee,
+				OrderFieldFunction, OrderFieldMessage, OrderFieldStack,
+			},

Also applies to: 223-225, 276-278, 281-283, 286-288, 328-330, 340-342, 352-354, 364-366, 390-392

🧰 Tools
🪛 golangci-lint (1.64.8)

145-145: File is not properly formatted

(gofumpt)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8329c71 and 9997486.

📒 Files selected for processing (4)
  • zapcore/console_encoder.go (3 hunks)
  • zapcore/console_encoder_test.go (1 hunks)
  • zapcore/encoder.go (1 hunks)
  • zapcore/json_encoder.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • zapcore/encoder.go
  • zapcore/json_encoder.go
  • zapcore/console_encoder.go
🧰 Additional context used
🧬 Code Graph Analysis (1)
zapcore/console_encoder_test.go (5)
zapcore/console_encoder.go (9)
  • OrderField (38-38)
  • OrderFieldTime (43-43)
  • OrderFieldLevel (45-45)
  • OrderFieldName (47-47)
  • OrderFieldCallee (49-49)
  • OrderFieldFunction (51-51)
  • OrderFieldMessage (53-53)
  • OrderFieldStack (55-55)
  • NewConsoleEncoder (89-100)
field.go (2)
  • String (222-224)
  • Time (347-352)
zapcore/encoder.go (1)
  • EncoderConfig (331-361)
zapcore/field.go (1)
  • StringType (67-67)
zapcore/entry.go (2)
  • Entry (143-150)
  • EntryCaller (70-76)
🪛 golangci-lint (1.64.8)
zapcore/console_encoder_test.go

145-145: File is not properly formatted

(gofumpt)


223-223: File is not properly formatted

(gofumpt)


248-248: File is not properly formatted

(gofumpt)


276-276: File is not properly formatted

(gofumpt)


281-281: File is not properly formatted

(gofumpt)


286-286: File is not properly formatted

(gofumpt)


328-328: File is not properly formatted

(gofumpt)


340-340: File is not properly formatted

(gofumpt)


352-352: File is not properly formatted

(gofumpt)


364-364: File is not properly formatted

(gofumpt)

🔇 Additional comments (4)
zapcore/console_encoder_test.go (4)

137-207: Great test coverage for the new field ordering functionality.

This test thoroughly covers various field ordering scenarios, from default order to custom orders with fields in different positions. The test cases are comprehensive and verify that the console encoder correctly respects the specified order of fields.

🧰 Tools
🪛 golangci-lint (1.64.8)

145-145: File is not properly formatted

(gofumpt)


209-213: Clean helper function implementation.

This helper function nicely encapsulates the creation of an encoder config with the specified field order, keeping the test code DRY.


215-266: Good test coverage for context fields with different ordering configurations.

The test properly verifies that context fields are correctly included in the output alongside the ordered entry fields.

🧰 Tools
🪛 golangci-lint (1.64.8)

223-223: File is not properly formatted

(gofumpt)


248-248: File is not properly formatted

(gofumpt)


313-416: Excellent test coverage for missing fields scenarios.

This test thoroughly covers various scenarios where fields may be missing from the entry, ensuring that the encoder handles these cases correctly. The test cases are comprehensive and well-structured.

🧰 Tools
🪛 golangci-lint (1.64.8)

328-328: File is not properly formatted

(gofumpt)


340-340: File is not properly formatted

(gofumpt)


352-352: File is not properly formatted

(gofumpt)


364-364: File is not properly formatted

(gofumpt)

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

Successfully merging this pull request may close these issues.

2 participants