]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - docs/logging.txt
0cff1a78d689c6373fcf5f5a7bf079b7f1ec4ec4
[tahoe-lafs/tahoe-lafs.git] / docs / logging.txt
1 = Tahoe Logging =
2
3 Tahoe uses the Foolscap logging mechanism (known as the "flog" subsystem) to
4 record information about what is happening inside the Tahoe node. This is
5 primarily for use by programmers and grid operators who want to find out what
6 went wrong.
7
8 The foolscap logging system is documented here:
9
10   http://foolscap.lothar.com/docs/logging.html
11
12 The foolscap distribution includes a utility named "flogtool" (usually at
13 /usr/bin/flogtool) which is used to get access to many foolscap logging
14 features.
15
16 Note that there are currently (in foolscap-0.3.2) a couple of problems in using
17 flogtool on Windows:
18
19 http://foolscap.lothar.com/trac/ticket/108 # set base to "." if not running from source
20 http://foolscap.lothar.com/trac/ticket/109 # make a "flogtool" executable that works on Windows
21
22 == Realtime Logging ==
23
24 When you are working on Tahoe code, and want to see what the node is doing,
25 the easiest tool to use is "flogtool tail". This connects to the tahoe node
26 and subscribes to hear about all log events. These events are then displayed
27 to stdout, and optionally saved to a file.
28
29 "flogtool tail" connects to the "logport", for which the FURL is stored in
30 BASEDIR/private/logport.furl . The following command will connect to this
31 port and start emitting log information:
32
33  flogtool tail BASEDIR/private/logport.furl
34
35 The "--save-to FILENAME" option will save all received events to a file,
36 where then can be examined later with "flogtool dump" or "flogtool
37 web-viewer". The --catch-up flag will ask the node to dump all stored events
38 before subscribing to new ones (without --catch-up, you will only hear about
39 events that occur after the tool has connected and subscribed).
40
41 == Incidents ==
42
43 Foolscap keeps a short list of recent events in memory. When something goes
44 wrong, it writes all the history it has (and everything that gets logged in
45 the next few seconds) into a file called an "incident". These files go into
46 BASEDIR/logs/incidents/ , in a file named
47 "incident-TIMESTAMP-UNIQUE.flog.bz2". The default definition of "something
48 goes wrong" is the generation of a log event at the log.WEIRD level or
49 higher, but other criteria could be implemented.
50
51 The typical "incident report" we've seen in a large Tahoe grid is about 40kB
52 compressed, representing about 1800 recent events.
53
54 These "flogfiles" have a similar format to the files saved by "flogtool tail
55 --save-to". They are simply lists of log events, with a small header to
56 indicate which event triggered the incident.
57
58 The "flogtool dump FLOGFILE" command will take one of these .flog.bz2 files
59 and print their contents to stdout, one line per event. The raw event
60 dictionaries can be dumped by using "flogtool dump --verbose FLOGFILE".
61
62 The "flogtool web-viewer" command can be used to examine the flogfile in a
63 web browser. It runs a small HTTP server and emits the URL on stdout. This
64 view provides more structure than the output of "flogtool dump": the
65 parent/child relationships of log events is displayed in a nested format.
66 "flogtool web-viewer" is still fairly immature.
67
68 == Working with flogfiles ==
69
70 The "flogtool filter" command can be used to take a large flogfile (perhaps
71 one created by the log-gatherer, see below) and copy a subset of events into
72 a second file. This smaller flogfile may be easier to work with than the
73 original. The arguments to "flogtool filter" specify filtering criteria: a
74 predicate that each event must match to be copied into the target file.
75 --before and --after are used to exclude events outside a given window of
76 time. --above will retain events above a certain severity level. --from
77 retains events send by a specific tubid. --strip-facility removes events that
78 were emitted with a given facility (like foolscap.negotiation or
79 tahoe.upload).
80
81 == Gatherers ==
82
83 In a deployed Tahoe grid, it is useful to get log information automatically
84 transferred to a central log-gatherer host. This offloads the (admittedly
85 modest) storage requirements to a different host and provides access to
86 logfiles from multiple nodes (webapi/storage/helper) nodes in a single place.
87
88 There are two kinds of gatherers. Both produce a FURL which needs to be
89 placed in the NODEDIR/log_gatherer.furl file (one FURL per line) of the nodes
90 that are to publish their logs to the gatherer. When the Tahoe node starts,
91 it will connect to the configured gatherers and offer its logport: the
92 gatherer will then use the logport to subscribe to hear about events.
93
94 The gatherer will write to files in its working directory, which can then be
95 examined with tools like "flogtool dump" as described above.
96
97 === Incident Gatherer ===
98
99 The "incident gatherer" only collects Incidents: records of the log events
100 that occurred just before and slightly after some high-level "trigger event"
101 was recorded. Each incident is classified into a "category": a short string
102 that summarizes what sort of problem took place. These classification
103 functions are written after examining a new/unknown incident. The idea is to
104 recognize when the same problem is happening multiple times.
105
106 A collection of classification functions that are useful for Tahoe nodes are
107 provided in misc/incident-gatherer/support_classifiers.py . There is roughly
108 one category for each log.WEIRD-or-higher level event in the Tahoe source
109 code.
110
111 The incident gatherer is created with the "flogtool create-incident-gatherer
112 WORKDIR" command, and started with "tahoe start". The generated
113 "gatherer.tac" file should be modified to add classifier functions.
114
115 The incident gatherer writes incident names (which are simply the relative
116 pathname of the incident-*.flog.bz2 file) into classified/CATEGORY. For
117 example, the classified/mutable-retrieve-uncoordinated-write-error file
118 contains a list of all incidents which were triggered by an uncoordinated
119 write that was detected during mutable file retrieval (caused when somebody
120 changed the contents of the mutable file in between the node's mapupdate step
121 and the retrieve step). The classified/unknown file contains a list of all
122 incidents that did not match any of the classification functions.
123
124 At startup, the incident gatherer will automatically reclassify any incident
125 report which is not mentioned in any of the classified/* files. So the usual
126 workflow is to examine the incidents in classified/unknown, add a new
127 classification function, delete classified/unknown, then bound the gatherer
128 with "tahoe restart WORKDIR". The incidents which can be classified with the
129 new functions will be added to their own classified/FOO lists, and the
130 remaining ones will be put in classified/unknown, where the process can be
131 repeated until all events are classifiable.
132
133 The incident gatherer is still fairly immature: future versions will have a
134 web interface and an RSS feed, so operations personnel can track problems in
135 the storage grid.
136
137 In our experience, each Incident takes about two seconds to transfer from the
138 node which generated it to the gatherer. The gatherer will automatically
139 catch up to any incidents which occurred while it is offline.
140
141 === Log Gatherer ===
142
143 The "Log Gatherer" subscribes to hear about every single event published by
144 the connected nodes, regardless of severity. This server writes these log
145 events into a large flogfile that is rotated (closed, compressed, and
146 replaced with a new one) on a periodic basis. Each flogfile is named
147 according to the range of time it represents, with names like
148 "from-2008-08-26-132256--to-2008-08-26-162256.flog.bz2". The flogfiles
149 contain events from many different sources, making it easier to correlate
150 things that happened on multiple machines (such as comparing a client node
151 making a request with the storage servers that respond to that request).
152
153 The Log Gatherer is created with the "flogtool create-gatherer WORKDIR"
154 command, and started with "tahoe start". The log_gatherer.furl it creates
155 then needs to be copied into the BASEDIR/log_gatherer.furl file of all nodes
156 which should be sending it log events.
157
158 The "flogtool filter" command, described above, is useful to cut down the
159 potentially-large flogfiles into more a narrowly-focussed form.
160
161 Busy nodes, particularly wapi nodes which are performing recursive
162 deep-size/deep-stats/deep-check operations, can produce a lot of log events.
163 To avoid overwhelming the node (and using an unbounded amount of memory for
164 the outbound TCP queue), publishing nodes will start dropping log events when
165 the outbound queue grows too large. When this occurs, there will be gaps
166 (non-sequential event numbers) in the log-gatherer's flogfiles.
167
168 == Local twistd.log files ==
169
170 [TODO: not yet true, requires foolscap-0.3.1 and a change to allmydata.node]
171
172 In addition to the foolscap-based event logs, certain high-level events will
173 be recorded directly in human-readable text form, in the
174 BASEDIR/logs/twistd.log file (and its rotated old versions: twistd.log.1,
175 twistd.log.2, etc). This form does not contain as much information as the
176 flogfiles available through the means described previously, but they are
177 immediately available to the curious developer, and are retained until the
178 twistd.log.NN files are explicitly deleted.
179
180 Only events at the log.OPERATIONAL level or higher are bridged to twistd.log
181 (i.e. not the log.NOISY debugging events). In addition, foolscap internal
182 events (like connection negotiation messages) are not bridged to twistd.log .
183
184 == Adding log messages ==
185
186 When adding new code, the Tahoe developer should add a reasonable number of
187 new log events. For details, please see the Foolscap logging documentation,
188 but a few notes are worth stating here:
189
190  * use a facility prefix of "tahoe.", like "tahoe.mutable.publish"
191
192  * assign each severe (log.WEIRD or higher) event a unique message
193    identifier, as the umid= argument to the log.msg() call. The
194    misc/make_umid script may be useful for this purpose. This will make it
195    easier to write a classification function for these messages.
196
197  * use the parent= argument whenever the event is causally/temporally
198    clustered with its parent. For example, a download process that involves
199    three sequential hash fetches could announce the send and receipt of those
200    hash-fetch messages with a parent= argument that ties them to the overall
201    download process. However, each new wapi download request should be
202    unparented.
203
204  * use the format= argument in preference to the message= argument. E.g.
205    use log.msg(format="got %(n)d shares, need %(k)d", n=n, k=k) instead of
206    log.msg("got %d shares, need %d" % (n,k)). This will allow later tools to
207    analyze the event without needing to scrape/reconstruct the structured
208    data out of the formatted string.
209
210  * Pass extra information as extra keyword arguments, even if they aren't
211    included in the format= string. This information will be displayed in the
212    "flogtool dump --verbose" output, as well as being available to other
213    tools. The umid= argument should be passed this way.
214
215  * use log.err for the catch-all addErrback that gets attached to the end of
216    any given Deferred chain. When used in conjunction with LOGTOTWISTED=1,
217    log.err() will tell Twisted about the error-nature of the log message,
218    causing Trial to flunk the test (with an "ERROR" indication that prints a
219    copy of the Failure, including a traceback). Don't use log.err for events
220    that are BAD but handled (like hash failures: since these are often
221    deliberately provoked by test code, they should not cause test failures):
222    use log.msg(level=BAD) for those instead.
223
224
225 == Log Messages During Unit Tests ==
226
227 *** WARNING: setting the environment variables below may cause some tests to   ***
228 *** fail spuriously. See ticket #923 for the status of a fix for this problem. ***
229
230 If a test is failing and you aren't sure why, start by enabling
231 FLOGTOTWISTED=1 like this:
232
233  make test FLOGTOTWISTED=1
234
235 With FLOGTOTWISTED=1, sufficiently-important log events will be written into
236 _trial_temp/test.log, which may give you more ideas about why the test is
237 failing.
238
239
240 If that isn't enough, look at the detailed foolscap logging messages instead,
241 by running the tests like this:
242
243  make test FLOGFILE=flog.out.bz2 FLOGLEVEL=1 FLOGTOTWISTED=1
244
245 The first environment variable will cause foolscap log events to be written
246 to ./flog.out.bz2 (instead of merely being recorded in the circular buffers
247 for the use of remote subscribers or incident reports). The second will cause
248 all log events to be written out, not just the higher-severity ones. The
249 third will cause twisted log events (like the markers that indicate when each
250 unit test is starting and stopping) to be copied into the flogfile, making it
251 easier to correlate log events with unit tests.
252
253 Enabling this form of logging appears to roughly double the runtime of the
254 unit tests. The flog.out.bz2 file is approximately 2MB.
255
256 You can then use "flogtool dump" or "flogtool web-viewer" on the resulting
257 flog.out file.
258
259 ("flogtool tail" and the log-gatherer are not useful during unit tests, since
260 there is no single Tub to which all the log messages are published).