Skip to content

Custom formatters

Pavel Korotkov edited this page Oct 12, 2016 · 7 revisions

If you feel that current set of standard formatters is not enough, you may specify your own custom formatters.

To do it you must use seelog.RegisterCustomFormatter func to register the factory for the new format alias you are going to use. After that (if returned error is nil) you can use the specified format alias in any loggers that you create afterwards.

Custom formatters can be parameterized. Parameter strings (inside brackets), if present, are passed to the factory func that you registered.

Let's look at a couple of examples.

Alternative log level names

Register your new formatter:

var myLevelToString = map[log.LogLevel]string{
	log.TraceLvl:    "MyTrace",
	log.DebugLvl:    "MyDebug",
	log.InfoLvl:     "MyInfo",
	log.WarnLvl:     "MyWarn",
	log.ErrorLvl:    "MyError",
	log.CriticalLvl: "MyCritical",
	log.Off:         "MyOff",
}

func createMyLevelFormatter(params string) log.FormatterFunc {
	return func(message string, level log.LogLevel, context log.LogContextInterface) interface{} {
		levelStr, ok := myLevelToString[level]
		if !ok {
			return "Broken level!"
		}
		return levelStr
	}
}

func init() {
    err := log.RegisterCustomFormatter("MyLevel", createMyLevelFormatter)
    if err != nil {
         ...
    }
}

Now you can use the registered 'MyLevel' in your configs:

<seelog type="sync">
	<outputs formatid="main">
		<console/>
	</outputs>
	<formats>
		<format id="main" format="%MyLevel %Msg%n"/>
	</formats>
</seelog>

After a logger is created using this config:

log.Trace("Test message!")

Output:

MyTrace Test message!

Formatter for TLS connection writing to syslog

Register your new formatter:

var hostName string
var appName = "test"
var pid int

var levelToSyslogSeverity = map[log.LogLevel]int{
	// Mapping to RFC 5424 where possible
	log.TraceLvl:    7,
	log.DebugLvl:    7,
	log.InfoLvl:     6,
	log.WarnLvl:     4,
	log.ErrorLvl:    3,
	log.CriticalLvl: 2,
	log.Off:         7,
}

func createSyslogHeaderFormatter(params string) log.FormatterFunc {
	facility := 20
	i, err := strconv.Atoi(params)
	if err == nil && i >= 0 && i <= 23 {
		facility = i
	}

	return func(message string, level log.LogLevel, context log.LogContextInterface) interface{} {
		return fmt.Sprintf("<%d>1 %s %s %s %d - -", facility*8+levelToSyslogSeverity[level],
			time.Now().Format("2006-01-02T15:04:05Z07:00"),
			hostName, appName, pid)
	}
}

func init() {
	hostName, _ = os.Hostname()
	pid = os.Getpid()

    err := log.RegisterCustomFormatter("CustomSyslogHeader", createSyslogHeaderFormatter)
    if err != nil {
        ...
    }
}

Now you can use the registered 'CustomSyslogHeader' in your configs:

<outputs>
  <conn formatid="syslog" net="tcp4" addr="server.address:5514" tls="true" insecureskipverify="true" />
</outputs>
<formats>
  <format id="syslog" format="%CustomSyslogHeader(20) %Msg%n"/>
</formats>

After a logger is created using this config:

log.Info("Test message!")

Output (to connection):

<167>1 2014-05-14T21:39:00+04:00 imp-pcl test 7624 - - Test message!