Skip to content

Performance

goodsign edited this page Aug 8, 2014 · 30 revisions

You don't pay for disabled log levels

If you have 'levels="off"' in your config, you don't get any visible effect from log statements.

Benchmark

Y-axis:Time(ns)

X-axis:Log statements count

Disabled

Different loggers

Read about different logger types here: Logger types

This benchmark shows you the difference in logger performance between fast async logger configurations and a really slow synchronous logger with a heavy format.

Benchmark

Y-axis:Time(ns)

X-axis:Log statements count

Configurations:

Default:

<seelog type="asyncloop">
	<outputs>
		<file path="..."/>
	</outputs>
</seelog>

Production:

<seelog type="asynctimer" asyncinterval="1000">
	<outputs formatid="msg">
		<file path="..."/>
	</outputs>
	<formats>
		<format id="msg" format="%Msg"/>
	</formats>
</seelog>

Debug (Synchronous):

<seelog type="sync">
	<outputs formatid="msg">
		<file path="..."/>
	</outputs>
	<formats>
		<format id="msg" format="%Ns %Level %Msg %FullPath %Func %Time %n"/>
	</formats>
</seelog>

Configs

What affects performance

  • Length of log message and arguments list
  • Dispatcher configuration
  • Format
  • Logger type (Sync/Async)

How exceptions count affect performance

Seelog iterates through the list of exceptions only once for each {file/func/loglevel} triplet.

So, if you perform log in the same file in the same func with the same log level twice, you get performance hit only the first time. After that the check result is put into a [file][func][level]->[bool] map and just retrieved from it until logger is recreated.

Performance recommendations

There are several simple recommendations, that almost gives you a guarantee that log operations won't noticeably affect your business logic performance in production. So, when you are running in production:

  • Don't use 'Info' (and above) messages in performance critical operations that are frequently called. Check Log levels wiki page.
  • Don't allow log levels below 'Info' both in global constraints AND in exceptions.
  • Try to avoid special calculations that are done just to log something. For example: log.Debugf("Result=%d", calculateResult()) would of course call 'calculateResults() every time, even if Debug is totally disabled.
  • Don't use too many exceptions.
  • Don't use heavy formats. For example, "%Date/%Time" verbs are really heavy in terms of logging. So use "%Ns" instead. Seelog uses a pretty fast log format by default, so if you don't change it, it's okay in terms of performance.
  • Use asynchronous behavior (Async timer has a minimal effect on performance)
  • Never use concatenation. Use 'log.Debugf("var1=%s",var1)' instead of 'log.Debugf("var1=" + var1)'.

These rules are for production. In development, you can use heavy formats to make log more readable (but more laggy) and do other things that would help debugging if performance is not so critical during development.