Skip to content
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

Customizing order of fields #446

Open
William010x opened this issue Jun 13, 2022 · 5 comments
Open

Customizing order of fields #446

William010x opened this issue Jun 13, 2022 · 5 comments

Comments

@William010x
Copy link

I want to be able to customize the order of fields, instead of having it sorted alphabetically.

Desired output: `[1] [2] [3] Message

Using PartsOrder to customize the order works, but it displays NIL for logs that don't have that field.

[%!S(<NIL>)] [%!S(<NIL>)] [%!S(<NIL>)] [%!S(<NIL>)] Message

Also, the field gets printed twice.

[1] [2] [3] Message A=[3] B=[2] C=[1]

How would I be able to do this?

If not possible, suggested change:

  • Add an attribute FormatWriteFields FieldsFormatter with type func FieldsFormatter (evt map[string]interface{}, buf *bytes.Buffer) that users can pass in (similar to the other formatters)

w.writeFields(evt, buf)

if w.FormatWriteFields == nil {
    w.writeFields(evt, buf)
} else {
    w.FormatWriteFields(evt, buf)
}
@William010x William010x changed the title Provide a way to customize order of fields Customizing order of fields Jun 13, 2022
@phuslu
Copy link

phuslu commented Jun 15, 2022

I think it's hard in zerolog because its console writer unmarshal input to map[string]interface{}.

I re-wrote a zerolog-like logger and a new console writer, the example for your requirement is here https://go.dev/play/p/UmJmLxYXwRO

@wooowlili
Copy link

The same request

@adubkov
Copy link

adubkov commented May 10, 2023

[1] [2] [3] Message A=[3] B=[2] C=[1]

This is definitely a bug and should be addressed.

@Alexandre-Stoppini-Cyberdian

Following here. I found a way to ignore this bug with this :

First, get variables and function colorize from the library :

const (
	colorBlack = iota + 30
	colorRed
	colorGreen
	colorYellow
	colorBlue
	colorMagenta
	colorCyan
	colorWhite

	colorBold     = 1
	colorDarkGray = 90

	unknownLevel = "???"
)

func colorize(s interface{}, c int) string {
	return fmt.Sprintf("\x1b[%dm%v\x1b[0m", c, s)
}

Configure standarOutput

	customStandardOutput:= zerolog.ConsoleWriter{
		Out:                 os.Stdout,
		NoColor:             false,
		TimeFormat:          time.Stamp,
		TimeLocation:        nil,
		PartsOrder:          []string{"level", "time", "application", "function", "message"},
		PartsExclude:        nil,
		FieldsOrder:         nil,
		FieldsExclude:       []string{"application", "function", "message"},
		FormatTimestamp:     nil,
		FormatLevel:         func(i interface{}) string { return strings.ToUpper(fmt.Sprintf("%-6s|", i)) }, // INFO  |
		FormatCaller:        nil,
		FormatMessage:       nil,
		FormatFieldName:     nil,
		FormatFieldValue:    nil,
		FormatErrFieldName:  nil,
		FormatErrFieldValue: nil,
		FormatExtra:         nil,
		FormatPrepare:       nil,
	}

Then, set the logger like

func SetLogger(application, function string) zerolog.Logger {

	return zerolog.New(customStandardOutput).With().Timestamp().
		Str("application", colorize("application=", colorCyan)+application).
		Str("function", colorize("function=", colorCyan)+function).
		Logger()

}

Test this function

func TestInitLogs(t *testing.T) {
	logger := SetLogger("myApp", "TestInitLogs")

	logger.Info().Msg("TestInitLogs")
}
image

@maxant
Copy link

maxant commented Oct 21, 2024

To avoid printing fields twice, configure FieldsExclude and add the fields you don't want printed twice, to that array.

It would be really useful if the function FormatFieldValue were called with the field name as well as the field value, so that you could format depending on which field it is. For example I want to trim the length of the package name, so that the message always starts after 40 columns in the terminal (after 23 for timestamp, 6 for level, a few spacers and 8 for the package name that I set when creating the logger). As a work around, I prepend "pkg:" to the value and then strip that if it is present and then trim/pad to the length 10.

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

No branches or pull requests

6 participants