Skip to content

Commit 059b527

Browse files
authored
Some logging documentation (#6498)
1 parent 8fcbfa7 commit 059b527

File tree

1 file changed

+396
-0
lines changed

1 file changed

+396
-0
lines changed
Lines changed: 396 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,396 @@
1+
---
2+
date: "2019-04-02T17:06:00+01:00"
3+
title: "Advanced: Logging Configuration"
4+
slug: "logging-configuration"
5+
weight: 55
6+
toc: true
7+
draft: false
8+
menu:
9+
sidebar:
10+
parent: "advanced"
11+
name: "Logging Configuration"
12+
weight: 55
13+
identifier: "logging-configuration"
14+
---
15+
16+
# Logging Configuration
17+
18+
The logging framework has been revamped in Gitea 1.9.0.
19+
20+
## Log Groups
21+
22+
The fundamental thing to be aware of in Gitea is that there are several
23+
log groups:
24+
25+
* The "Default" logger
26+
* The Macaron logger
27+
* The Router logger
28+
* The Access logger
29+
* The XORM logger
30+
* A logger called the `GitLogger` which is used during hooks.
31+
32+
There is also the go log logger.
33+
34+
### The go log logger
35+
36+
Go provides its own extremely basic logger in the `log` package,
37+
however, this is not sufficient for our purposes as it does not provide
38+
a way of logging at multiple levels, nor does it provide a good way of
39+
controlling where these logs are logged except through setting of a
40+
writer.
41+
42+
We have therefore redirected this logger to our Default logger, and we
43+
will log anything that is logged using the go logger at the INFO level.
44+
45+
### The "Default" logger
46+
47+
Calls to `log.Info`, `log.Debug`, `log.Error` etc. from the `code.gitea.io/gitea/modules/log` package will log to this logger.
48+
49+
You can configure the outputs of this logger by setting the `MODE`
50+
value in the `[log]` section of the configuration.
51+
52+
Each output sublogger is configured in a separate `[log.sublogger]`
53+
section, but there are certain default values. These will not be inherited from the `[log]` section:
54+
55+
* `FLAGS` is `stdflags` (Equal to
56+
`date,time,medfile,shortfuncname,levelinitial`)
57+
* `FILE_NAME` will default to `%(ROOT_PATH)/gitea.log`
58+
* `EXPRESSION` will default to `""`
59+
* `PREFIX` will default to `""`
60+
61+
The provider type of the sublogger can be set using the `MODE` value in
62+
its subsection, but will default to the name. This allows you to have
63+
multiple subloggers that will log to files.
64+
65+
### The "Macaron" logger
66+
67+
By default Macaron will log to its own go `log` instance. This writes
68+
to `os.Stdout`. You can redirect this log to a Gitea configurable logger
69+
through setting the `ENABLE_MACARON_REDIRECT` setting in the `[log]`
70+
section which you can configure the outputs of by setting the `MACARON`
71+
value in the `[log]` section of the configuration. `MACARON` defaults
72+
to `file` if unset.
73+
74+
Each output sublogger for this logger is configured in
75+
`[log.sublogger.macaron]` sections. There are certain default values
76+
which will not be inherited from the `[log]` or relevant
77+
`[log.sublogger]` sections:
78+
79+
* `FLAGS` is `stdflags` (Equal to
80+
`date,time,medfile,shortfuncname,levelinitial`)
81+
* `FILE_NAME` will default to `%(ROOT_PATH)/macaron.log`
82+
* `EXPRESSION` will default to `""`
83+
* `PREFIX` will default to `""`
84+
85+
NB: You can redirect the macaron logger to send its events to the gitea
86+
log using the value: `MACARON = ,`
87+
88+
### The "Router" logger
89+
90+
There are two types of Router log. By default Macaron send its own
91+
router log which will be directed to Macaron's go `log`, however if you
92+
`ENABLE_MACARON_REDIRECT` you will enable Gitea's router log. You can
93+
disable both types of Router log by setting `DISABLE_ROUTER_LOG`.
94+
95+
If you enable the redirect, you can configure the outputs of this
96+
router log by setting the `ROUTER` value in the `[log]` section of the
97+
configuration. `ROUTER` will default to `console` if unset. The Gitea
98+
Router logs the same data as the Macaron log but has slightly different
99+
coloring. It logs at the `Info` level by default, but this can be
100+
changed if desired by setting the `ROUTER_LOG_LEVEL` value.
101+
102+
Each output sublogger for this logger is configured in
103+
`[log.sublogger.router]` sections. There are certain default values
104+
which will not be inherited from the `[log]` or relevant
105+
`[log.sublogger]` sections:
106+
107+
* `FILE_NAME` will default to `%(ROOT_PATH)/router.log`
108+
* `FLAGS` defaults to `date,time`
109+
* `EXPRESSION` will default to `""`
110+
* `PREFIX` will default to `""`
111+
112+
NB: You can redirect the router logger to send its events to the Gitea
113+
log using the value: `ROUTER = ,`
114+
115+
### The "Access" logger
116+
117+
The Access logger is a new logger for version 1.9. It provides a NCSA
118+
Common Log compliant log format. It's highly configurable but caution
119+
should be taken when changing its template. The main benefit of this
120+
logger is that Gitea can now log accesses in a standard log format so
121+
standard tools may be used.
122+
123+
You can enable this logger using `ENABLE_ACCESS_LOG`. Its outputs are
124+
configured by setting the `ACCESS` value in the `[log]` section of the
125+
configuration. `ACCESS` defaults to `file` if unset.
126+
127+
Each output sublogger for this logger is configured in
128+
`[log.sublogger.access]` sections. There are certain default values
129+
which will not be inherited from the `[log]` or relevant
130+
`[log.sublogger]` sections:
131+
132+
* `FILE_NAME` will default to `%(ROOT_PATH)/access.log`
133+
* `FLAGS` defaults to `` or None
134+
* `EXPRESSION` will default to `""`
135+
* `PREFIX` will default to `""`
136+
137+
If desired the format of the Access logger can be changed by changing
138+
the value of the `ACCESS_LOG_TEMPLATE`.
139+
140+
NB: You can redirect the access logger to send its events to the Gitea
141+
log using the value: `ACCESS = ,`
142+
143+
#### The ACCESS_LOG_TEMPLATE
144+
145+
This value represent a go template. It's default value is:
146+
147+
`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`
148+
149+
The template is passed following options:
150+
151+
* `Ctx` is the `macaron.Context`
152+
* `Identity` is the `SignedUserName` or `"-"` if the user is not logged
153+
in
154+
* `Start` is the start time of the request
155+
* `ResponseWriter` is the `macaron.ResponseWriter`
156+
157+
Caution must be taken when changing this template as it runs outside of
158+
the standard panic recovery trap. The template should also be as simple
159+
as it runs for every request.
160+
161+
### The "XORM" logger
162+
163+
The XORM logger is a long-standing logger that exists to collect XORM
164+
log events. It is enabled by default but can be switched off by setting
165+
`ENABLE_XORM_LOG` to `false` in the `[log]` section. Its outputs are
166+
configured by setting the `XORM` value in the `[log]` section of the
167+
configuration. `XORM` defaults to `,` if unset, meaning it is redirected
168+
to the main Gitea log.
169+
170+
XORM will log SQL events by default. This can be changed by setting
171+
the `LOG_SQL` value to `false` in the `[database]` section.
172+
173+
Each output sublogger for this logger is configured in
174+
`[log.sublogger.xorm]` sections. There are certain default values
175+
which will not be inherited from the `[log]` or relevant
176+
`[log.sublogger]` sections:
177+
178+
* `FILE_NAME` will default to `%(ROOT_PATH)/xorm.log`
179+
* `FLAGS` defaults to `date,time`
180+
* `EXPRESSION` will default to `""`
181+
* `PREFIX` will default to `""`
182+
183+
### The Hook and Serv "GitLoggers"
184+
185+
These are less well defined loggers. Essentially these should only be
186+
used within Gitea's subsystems and cannot be configured at present.
187+
188+
They will write log files in:
189+
190+
* `%(ROOT_PATH)/hooks/pre-receive.log`
191+
* `%(ROOT_PATH)/hooks/update.log`
192+
* `%(ROOT_PATH)/hooks/post-receive.log`
193+
* `%(ROOT_PATH)/serv.log`
194+
* `%(ROOT_PATH)/http.log`
195+
196+
In the future these logs may be rationalised.
197+
198+
## Log outputs
199+
200+
Gitea provides 4 possible log outputs:
201+
202+
* `console` - Log to `os.Stdout` or `os.Stderr`
203+
* `file` - Log to a file
204+
* `conn` - Log to a keep-alive TCP connection
205+
* `smtp` - Log via email
206+
207+
Certain configuration is common to all modes of log output:
208+
209+
* `LEVEL` is the lowest level that this output will log. This value
210+
is inherited from `[log]` and in the case of the non-default loggers
211+
from `[log.sublogger]`.
212+
* `STACKTRACE_LEVEL` is the lowest level that this output will print
213+
a stacktrace. This value is inherited.
214+
* `MODE` is the mode of the log output. It will default to the sublogger
215+
name. Thus `[log.console.macaron]` will default to `MODE = console`.
216+
* `COLORIZE` will default to `true` for `file` and `console` as
217+
described, otherwise it will default to `false`.
218+
219+
### Non-inherited default values
220+
221+
There are several values which are not inherited as described above but
222+
rather default to those specific to type of logger, these are:
223+
`EXPRESSION`, `FLAGS`, `PREFIX` and `FILE_NAME`.
224+
225+
#### `EXPRESSION`
226+
227+
`EXPRESSION` represents a regular expression that log events must match to be logged by the sublogger. Either the log message, (with colors removed), must match or the `longfilename:linenumber:functionname` must match. NB: the whole message or string doesn't need to completely match.
228+
229+
Please note this expression will be run in the sublogger's goroutine
230+
not the logging event subroutine. Therefore it can be complicated.
231+
232+
#### `FLAGS`
233+
234+
`FLAGS` represents the preceding logging context information that is
235+
printed before each message. It is a comma-separated string set. The order of values does not matter.
236+
237+
Possible values are:
238+
239+
* `none` or `,` - No flags.
240+
* `date` - the date in the local time zone: `2009/01/23`.
241+
* `time` - the time in the local time zone: `01:23:23`.
242+
* `microseconds` - microsecond resolution: `01:23:23.123123`. Assumes
243+
time.
244+
* `longfile` - full file name and line number: `/a/b/c/d.go:23`.
245+
* `shortfile` - final file name element and line number: `d.go:23`.
246+
* `funcname` - function name of the caller: `runtime.Caller()`.
247+
* `shortfuncname` - last part of the function name. Overrides
248+
`funcname`.
249+
* `utc` - if date or time is set, use UTC rather than the local time
250+
zone.
251+
* `levelinitial` - Initial character of the provided level in brackets eg. `[I]` for info.
252+
* `level` - Provided level in brackets `[INFO]`
253+
* `medfile` - Last 20 characters of the filename - equivalent to
254+
`shortfile,longfile`.
255+
* `stdflags` - Equivalent to `date,time,medfile,shortfuncname,levelinitial`
256+
257+
### Console mode
258+
259+
For loggers in console mode, `COLORIZE` will default to `true` if not
260+
on windows, or the windows terminal can be set into ANSI mode or is a
261+
cygwin or Msys pipe.
262+
263+
If `STDERR` is set to `true` the logger will use `os.Stderr` instead of
264+
`os.Stdout`.
265+
266+
### File mode
267+
268+
The `FILE_NAME` defaults as described above. If set it will be relative
269+
to the provided `ROOT_PATH` in the master `[log]` section.
270+
271+
Other values:
272+
273+
* `LOG_ROTATE`: **true**: Rotate the log files.
274+
* `MAX_SIZE_SHIFT`: **28**: Maximum size shift of a single file, 28 represents 256Mb.
275+
* `DAILY_ROTATE`: **true**: Rotate logs daily.
276+
* `MAX_DAYS`: **7**: Delete the log file after n days
277+
* NB: `COLORIZE`: will default to `true` if not on windows.
278+
* `COMPRESS`: **true**: Compress old log files by default with gzip
279+
* `COMPRESSION_LEVEL`: **-1**: Compression level
280+
281+
### Conn mode
282+
283+
* `RECONNECT_ON_MSG`: **false**: Reconnect host for every single message.
284+
* `RECONNECT`: **false**: Try to reconnect when connection is lost.
285+
* `PROTOCOL`: **tcp**: Set the protocol, either "tcp", "unix" or "udp".
286+
* `ADDR`: **:7020**: Sets the address to connect to.
287+
288+
### SMTP mode
289+
290+
It is not recommended to use this logger to send general logging
291+
messages. However, you could perhaps set this logger to work on `FATAL`.
292+
293+
* `USER`: User email address to send from.
294+
* `PASSWD`: Password for the smtp server.
295+
* `HOST`: **127.0.0.1:25**: The SMTP host to connect to.
296+
* `RECEIVERS`: Email addresses to send to.
297+
* `SUBJECT`: **Diagnostic message from Gitea**
298+
299+
## Default Configuration
300+
301+
The default empty configuration is equivalent to:
302+
303+
```ini
304+
[log]
305+
ROOT_PATH = %(GITEA_WORK_DIR)/log
306+
MODE = console
307+
LEVEL = Info
308+
STACKTRACE_LEVEL = None
309+
REDIRECT_MACARON_LOG = false
310+
ENABLE_ACCESS_LOG = false
311+
ENABLE_XORM_LOG = true
312+
XORM = ,
313+
314+
[log.console]
315+
MODE = console
316+
LEVEL = %(LEVEL)
317+
STACKTRACE_LEVEL = %(STACKTRACE_LEVEL)
318+
FLAGS = stdflags
319+
PREFIX =
320+
COLORIZE = true # Or false if your windows terminal cannot color
321+
```
322+
323+
This is equivalent to sending all logs to the console, with default go log being sent to the console log too.
324+
325+
## Log colorization
326+
327+
Logs to the console will be colorized by default when not running on
328+
Windows. Terminal sniffing will occur on Windows and if it is
329+
determined that we are running on a terminal capable of color we will
330+
colorize.
331+
332+
Further, on *nix it is becoming common to have file logs that are
333+
colored by default. Therefore file logs will be colorised by default
334+
when not running on Windows.
335+
336+
You can switch on or off colorization by using the `COLORIZE` value.
337+
338+
From a development point of view. If you write
339+
`log.Info("A %s string", "formatted")` the `formatted` part of the log
340+
message will be Bolded on colorized logs.
341+
342+
You can change this by either rendering the formatted string yourself.
343+
Or you can wrap the value in a `log.ColoredValue` struct.
344+
345+
The `log.ColoredValue` struct contains a pointer to value, a pointer to
346+
string of bytes which should represent a color and second set of reset
347+
bytes. Pointers were chosen to prevent copying of large numbers of
348+
values. There are several helper methods:
349+
350+
* `log.NewColoredValue` takes a value and 0 or more color attributes
351+
that represent the color. If 0 are provided it will default to a cached
352+
bold. Note, it is recommended that color bytes constructed from
353+
attributes should be cached if this is a commonly used log message.
354+
* `log.NewColoredValuePointer` takes a pointer to a value, and
355+
0 or more color attributes that represent the color.
356+
* `log.NewColoredValueBytes` takes a value and a pointer to an array
357+
of bytes representing the color.
358+
359+
These functions will not double wrap a `log.ColoredValue`. They will
360+
also set the ResetBytes to the cached resetBytes.
361+
362+
Be careful not to change the contents of resetBytes or boldBytes as this
363+
will break rendering of logging elsewhere. You have been warned.
364+
365+
## Log Spoofing protection
366+
367+
In order to protect the logs from being spoofed with cleverly
368+
constructed messages. Newlines are now prefixed with a tab and control
369+
characters except those used in an ANSI CSI are escaped with a
370+
preceding `\` and their octal value.
371+
372+
## Creating a new named logger group
373+
374+
Should a developer wish to create a new named logger, `NEWONE`. It is
375+
recommended to add an `ENABLE_NEWONE_LOG` value to the `[log]`
376+
section, and to add a new `NEWONE` value for the modes.
377+
378+
A function like `func newNewOneLogService()` is recommended to manage
379+
construction of the named logger. e.g.
380+
381+
```go
382+
func newNewoneLogService() {
383+
EnableNewoneLog = Cfg.Section("log").Key("ENABLE_NEWONE_LOG").MustBool(false)
384+
Cfg.Section("log").Key("NEWONE").MustString("file") // or console? or "," if you want to send this to default logger by default
385+
if EnableNewoneLog {
386+
options := newDefaultLogOptions()
387+
options.filename = filepath.Join(LogRootPath, "newone.log")
388+
options.flags = "stdflags"
389+
options.bufferLength = Cfg.Section("log").Key("BUFFER_LEN").MustInt64(10000)
390+
generateNamedLogger("newone", options)
391+
}
392+
}
393+
```
394+
395+
You should then add `newOneLogService` to `NewServices()` in
396+
`modules/setting/setting.go`

0 commit comments

Comments
 (0)