root/ChangeLog

Revision 509:66eb3cffca75, 169.5 kB (checked in by Brian Warner <warner@allmydata.com>, 1 month ago)

include classify_foolscap.py in the debian package, ready for symlinking

Line 
1 2008-10-15  Brian Warner  <warner@allmydata.com>
2
3         * misc/*/debian/rules (install/python-foolscap): include
4         misc/classify_foolscap.py in the debian package, uncompressed, so
5         it goes into /usr/share/doc/python-foolscap/classify_foolscap.py ,
6         so you can make a symlink to it from an incident-gatherer.
7
8         * misc/classify_foolscap.py (TUBCON_RE): update to match
9         foolscap-tubconnector messages for both old and new versions of
10         Foolscap, and for python2.4 and 2.5 .
11
12         * foolscap/logging/incident.py (IncidentClassifier): add --verbose
13         option to 'flogtool classify-incident' to show the trigger
14         dictionary for any unclassifiable incidents. This is useful when
15         developing classification functions.
16         * foolscap/test/test_logging.py (Incidents.test_classify): test it
17
18         * Makefile (test-figleaf): oops, fix the test-figleaf-poll target,
19         by making the test-figleaf target use $(TRIAL), not hardcoded
20         'trial'.
21
22         * foolscap/_version.py: bump revision to 0.3.2+ while between releases
23         * misc/{dapper|edgy|feisty|gutsy|hardy|sarge|etch|sid}/debian/changelog:
24         same
25
26 2008-10-14  Brian Warner  <warner@lothar.com>
27
28         * foolscap/_version.py: release Foolscap-0.3.2
29         * misc/{dapper|edgy|feisty|gutsy|hardy|sarge|etch|sid}/debian/changelog:
30         same
31
32         * MANIFEST.in: add misc/classify_foolscap.py to source distribution
33
34         * NEWS: update for the next release
35
36         * Makefile (test-poll): add a convenience target, for running
37         tests on a system with the broken combination of pyopenssl and
38         twisted that requires the pollreactor
39         (test-figleaf-poll): same
40
41 2008-10-14  Brian Warner  <warner@allmydata.com>
42
43         * foolscap/logging/tail.py (LogTail): include the retrieved PID in
44         the saved logfile. Part of #80.
45         * foolscap/logging/incident.py (IncidentReporter.incident_declared):
46         also include the PID in the incident report's header.
47         * doc/specifications/logfiles.xhtml: document the ['versions']
48         and ['pid'] fields in incident reports and the 'flogtool tail'
49         savefile.
50
51
52         * foolscap/logging/web.py: mark any incident triggers in the
53         logfile, and add links to them from the welcome page. Closes #79.
54
55         * foolscap/logging/web.py (Reload): add a 'Reload Logfile' button
56         to the web-viewer's Welcome page. Not automatic, but it means you
57         don't have to get back to the shell and restart the viewer. Works
58         well-enough to say Closes #103.
59
60         * misc/classify_foolscap.py: plugin to classify some
61         foolscap-internal incidents
62
63         * foolscap/logging/cli.py: new "flogtool classify-incident"
64         subcommand: given an incident, say what categories it falls into.
65         Closes #102.
66         * foolscap/logging/gatherer.py (IncidentGathererService): factor
67         out the classification pieces into IncidentClassifierBase
68         * foolscap/logging/incident.py (IncidentClassifierBase): same
69         (IncidentClassifier.run): support for the new CLI command
70         * foolscap/test/test_logging.py (Incidents.test_classify): test it
71
72         * foolscap/logging/gatherer.py
73         (IncidentGathererService.classify_incident): change the classifier
74         function signature: now it just takes a single 'trigger' dict.
75         * foolscap/test/test_logging.py: update to match
76         * doc/logging.xhtml (gatherer): same
77
78         * foolscap/logging/gatherer.py
79         (IncidentGathererService.add_classify_files): make the incident
80         gatherer look in its base directory for "classify_*.py" files, use
81         them as plugins with classification functions.
82         (INCIDENT_GATHERER_TACFILE): update example text to match
83
84         * foolscap/test/test_logging.py (IncidentGatherer): test it
85         (Gatherer.test_wrongdir): exercise another error case
86         * doc/logging.xhtml (gatherer): document it
87
88 2008-10-13  Brian Warner  <warner@allmydata.com>
89
90         * foolscap/logging/publish.py (IncidentSubscription.catch_up):
91         Don't tell the gatherer about incidents that don't have triggers:
92         these are malformed logfiles, such as the zero-length files that
93         result from a process being terminated before it manages to write
94         anything.
95
96         * foolscap/logging/log.py (Count): replace itertools.count with a
97         version that doesn't overflow at 2**31-1 (thanks to Zooko for the
98         patch). Closes #99.
99         (FoolscapLogger.__init__): use it
100
101         * foolscap/pb.py (Listener.startFactory): add log facility
102         identifiers
103         (Listener.stopFactory): same
104         (Listener.buildProtocol): same
105         (Tub.getReference): same
106
107 2008-09-20  Brian Warner  <warner@lothar.com>
108
109         * doc/listings/xfer-client.py (_failure): do sys.exit(1) upon
110         failure, so the caller can detect it via the exit code
111
112 2008-09-10  Brian Warner  <warner@allmydata.com>
113
114         * foolscap/test/test__versions.py (Versions.test_required): check
115         for bug #62 (openssl>0.7, twisted<=8.1.0, selectreactor) and print
116         a warning if it is likely that the tests would fail, to remind the
117         user to re-run with -r poll.
118         (Versions.test_required): oops, guard import of OpenSSL on having
119         crypto available, otherwise this test gets an error when OpenSSL
120         is not installed.
121
122 2008-09-08  Brian Warner  <warner@lothar.com>
123
124         * doc/listings/xfer-client.py: use os.path.expanduser() on the
125         filenames passed in by the user, to enable things like
126         --furlfile ~/.upload.furl
127
128         * foolscap/_version.py: bump revision to 0.3.1+ while between releases
129         * misc/{dapper|edgy|feisty|gutsy|hardy|sarge|etch|sid}/debian/changelog:
130         same
131
132 2008-09-03  Brian Warner  <warner@lothar.com>
133
134         * foolscap/_version.py: release Foolscap-0.3.1
135         * misc/{dapper|edgy|feisty|gutsy|hardy|sarge|etch|sid}/debian/changelog:
136         same
137
138         * NEWS: update for next release
139
140 2008-09-02  Brian Warner  <warner@lothar.com>
141
142         * foolscap/negotiate.py (TubConnector.__repr__): add more
143         information to the repr, to help track down #81. Made TubConnector
144         a new-style class in the process, to make upcalling easier.
145         (TubConnector.checkForIdle): improve the log message
146
147         * foolscap/pb.py (Tub._log_gatherer_connected): use callRemoteOnly
148         to pass the logport to the gatherer: we don't need to hear about
149         any problems it has.
150
151         * foolscap/logging/gatherer.py
152         (IncidentGathererService.classify_stored_incidents): reclassify
153         everything that isn't already present in one of the classified/*
154         files. This makes it a lot easier to iterate over the [start
155         gatherer; see what is unknown; update classifiers; remove
156         classified/unknown; repeat] loop. Also log classification events
157         better. Closes #94.
158         * foolscap/test/test_logging.py (IncidentGatherer.test_emit): test it
159
160         * foolscap/test/common.py (PollMixin): replace the use of chained
161         Deferreds with a task.LoopingCall-based version, from Tahoe. This
162         avoids the weird and annoying maximum-recursion-depth-exceeded
163         error that occurs when the check function is called more than
164         about 600 times. Closes #95.
165
166 2008-08-29  Brian Warner  <warner@lothar.com>
167
168         * foolscap/logging/app_versions.py (versions): move the
169         application version dict (which gets reported to remote
170         subscribers, and copied into logfiles) to a separate module. It
171         was causing circular import problems when it lived in an attribute
172         of LogPublisher.
173         (add_version): provide a setter method
174         * foolscap/logging/publish.py (LogPublisher.versions): same
175         (LogPublisher.remote_get_versions): same
176         * foolscap/logging/incident.py (IncidentReporter.incident_declared):
177         same
178
179         * foolscap/test/test_logging.py (IncidentGatherer.test_emit):
180         improve test shutdown a little bit
181
182 2008-08-28  Brian Warner  <warner@lothar.com>
183
184         * foolscap/logging/incident.py (IncidentReporter.incident_declared):
185         put versions in the incident header too, also for #80.
186         * foolscap/test/test_logging.py (Incidents.test_basic): test it
187
188         * foolscap/logging/tail.py (LogPrinter.got_versions): record
189         remote application versions to the --save-to file, in the header.
190         Part of #80.
191         (LogPrinter.got_versions): oops, control where stdout goes
192         * foolscap/logging/dumper.py (LogDumper.start): show those
193         versions with --verbose
194         * foolscap/test/test_logging.py (Dumper.test_dump): update to match
195         (Tail.test_logprinter): same, make sure got_versions is called
196
197         * foolscap/logging/gatherer.py (IncidentObserver): only fetch one
198         incident at a time, to limit the size of the sender's outbound
199         queue. This should help close #85.
200         (IncidentGathererService.new_incident): include the classification
201         results in the per-incident log messages
202         * foolscap/test/test_logging.py (IncidentGatherer.test_emit): tests
203
204         * foolscap/logging/log.py (FoolscapLogger.declare_incident):
205         combine overlapping incidents, by passing new triggers to an
206         existing reporter instead of creating a new one. Helps with #85.
207         * foolscap/logging/incident.py (IncidentReporter.new_trigger): new
208         method to add subsequent triggers to an existing reporter. This
209         doesn't do anything yet. It should be improved to record the other
210         triggers in a trailer (since it's too late to add it to the
211         header). Every triggering event will make it into an incident
212         somewhere, but the report-file analysis tools may not know how to
213         pay attention to the subsequent triggers.
214         * foolscap/logging/interfaces.py (IIncidentReporter.new_trigger): same
215         * foolscap/test/test_logging.py (Incidents.test_overlapping): test it
216         * doc/logging.xhtml: mention incident-coalescing
217
218         * foolscap/logging/log.py: add bridge-foolscap-logs-to-twisted
219         functionality, set up by either calling bridgeLogsToTwisted(), or
220         by setting the FLOGTOTWISTED environment variable (to anything).
221         The default filter will exclude events below the OPERATIONAL
222         severity level, and those generated by foolscap internals (i.e.
223         facility.startswith("foolscap") ). Closes #93.
224         * foolscap/pb.py (Tub.setOption): update to match
225         * foolscap/test/test_logging.py (Bridge): tests for it
226         (Publish): update to use new APIs
227         * doc/logging.xhtml: docs
228
229 2008-08-25  Brian Warner  <warner@lothar.com>
230
231         * foolscap/broker.py (Broker.abandonAllRequests): map both
232         ConnectionLost and ConnectionDone into DeadReferenceError, so that
233         application code only needs to check for one exception type.
234         * foolscap/negotiate.py (Negotiation.evaluateNegotiationVersion1):
235         when an existing connection is dropped in favor of a new one, drop
236         it with DeadReferenceError instead of ConnectionDone. The mapping
237         in Broker.abandonAllRequests doesn't seem to quite catch
238         everything in unit tests.
239         (Negotiation.acceptDecisionVersion1): same, when we're the slave
240         * foolscap/test/test_call.py (TestCall.test_connection_lost_is_deadref):
241         test it
242         (TestCall.test_connection_done_is_deadref): same
243         (TestCall.testChoiceOf): switch to use ShouldFailMixin
244         * foolscap/test/test_gifts.py (Gifts): remove
245         ignoreConnectionDone, just look for DeadReferenceError
246
247 2008-08-21  Brian Warner  <warner@lothar.com>
248
249         * foolscap/_version.py (verstr): bump revision to 0.3.0+ while
250         between releases
251         * misc/{dapper|edgy|feisty|gutsy|hardy|sarge|etch|sid}/debian/changelog:
252         same
253
254 2008-08-04  Brian Warner  <warner@lothar.com>
255
256         * foolscap/_version.py (verstr): release Foolscap-0.3.0
257         * misc/{dapper|edgy|feisty|gutsy|hardy|sarge|etch|sid}/debian/changelog:
258
259 2008-08-04  Brian Warner  <warner@lothar.com>
260
261         * foolscap/logging/interfaces.py
262         (RILogPublisher.subscribe_to_incidents): small edit, make it more
263         clear that since= is used for catch_up=True
264
265         * NEWS: update for the upcoming release
266
267         * foolscap/referenceable.py (RemoteReferenceOnly.getRemoteTubID):
268         make this secure, by using the broker's .remote_tubref field,
269         instead of the remote-side-controlled sturdyref.
270         (RemoteReferenceOnly.getSturdyRef): add a note about the
271         insecurity of this method
272         * foolscap/test/test_pb.py (TestCallable.testGetSturdyRef): add a
273         test for getRemoteTubID
274
275         * doc/logging.xhtml: change filenames in the incident-gatherer to
276         have fewer files starting with incident*, so tab-completion works
277         better.
278         * foolscap/logging/gatherer.py (IncidentGathererService): same
279         (create_incident_gatherer): same
280
281         * foolscap/test/test_logging.py (Filter): test 'flogtool filter'
282         * foolscap/logging/filter.py: control stdout/stderr better
283
284         * foolscap/test/test_logging.py (Dumper): test 'flogtool dump'
285
286         * foolscap/logging/cli.py (dispatch): pass stdout/stderr through
287         attributes on the subcommand's Options instance, rather than as
288         separate function arguments.. makes testing easier.
289         * foolscap/logging/gatherer.py (create_log_gatherer): same
290         (create_incident_gatherer): same
291         (CreateGatherOptions): same
292         (CreateIncidentGatherOptions): same
293         * foolscap/logging/dumper.py (DumpOptions): same
294
295 2008-08-01  Brian Warner  <warner@lothar.com>
296
297         * foolscap/logging/log.py (LogFileObserver): make these more
298         useful, by not doing the addSystemEventTrigger in __init__
299         (LogFileObserver.stop_on_shutdown): do it here instead
300         (FLOGFILE): when using $FLOGFILE, add call to stop_on_shutdown
301
302         * foolscap/logging/gatherer.py (GathererService.do_rotate): oops,
303         implement the precautions claimed by the comment in startService:
304         test self._savefile before doing anything.
305         (GathererService.__init__): set self._savefile to None
306         * foolscap/test/test_logging.py (Gatherer.test_log_gatherer2): add
307         a timed rotator, which caught the problem in do_rotate
308
309         * foolscap/test/test_logging.py (IncidentGatherer.test_emit): add
310         test coverage for re-classifying existing incidents
311         (IncidentGatherer.test_emit._update_classifiers_again): and verify
312         that leaving the classified/ directory in place properly inhibits
313         reclassification at startup
314
315         * foolscap/referenceable.py (RemoteReferenceOnly.getRemoteTubID):
316         new method to extract the remote tubid from a RemoteReference. I'm
317         not sure this is a good idea, but it fixes the immediate problem
318         I'm dealing with.
319         * foolscap/logging/gatherer.py: use "tubid_s" instead of "nodeid_s"
320         (IncidentGathererService.remote_logport): use getRemoteTubID()
321         instead of trying to sanitize the tubid we receive, since we
322         use it as a directory name
323         (IncidentGathererService.add_classifier): rename addClassifier to
324         add_classifier, I'm more fond of the latter form these days. Also
325         remove a pyflakes warning.
326
327         * foolscap/test/test_logging.py (IncidentGatherer.test_emit): add
328         test of incident generation, publish, recording, and default
329         classification
330
331         * foolscap/logging/gatherer.py (IncidentGathererService): get
332         control over stdout, so we can exercise more code during tests
333         (IncidentGathererService.startService): oops, this needs to be
334         startService instead of start
335
336         * foolscap/test/test_logging.py (IncidentGatherer): basic test of
337         an incident gatherer, just setup and connection so far
338
339         * foolscap/test/common.py (StallMixin): factor stall() out into a
340         separate class
341         (TargetMixin): same
342
343         * foolscap/test/test_logging.py (LogfileReaderMixin): refactor
344         (Gatherer.test_log_gatherer): turn on bzip=True, for more coverage
345
346         * foolscap/test/test_logging.py (Gatherer._check_gatherer): ignore
347         internal foolscap messages (like connection negotiation), since
348         they occur at unpredictable times (specifically in
349         test_log_gatherer_furlfile_multiple, which has establishes
350         multiple connections)
351
352         * foolscap/test/common.py (GoodEnoughTub): factor this and
353         crypto_available out of all the other unit tests, make
354         GoodEnoughTub(certFile=) work even if crypto is unavailable and
355         we must therefore discard the certFile= argument.
356         * foolscap/test/test_crypto.py: same
357         * foolscap/test/test_gifts.py: same
358         * foolscap/test/test_keepalive.py: same
359         * foolscap/test/test_logging.py: same
360         * foolscap/test/test_loopback.py: same
361         * foolscap/test/test_negotiate.py: same
362         * foolscap/test/test_pb.py: same
363         * foolscap/test/test_serialize.py: same
364         * foolscap/test/test_tub.py: same
365
366         * foolscap/logging/gatherer.py (GatheringBase): rewrite Gatherers
367         to make them easier to test: now they are a Service (with a
368         subordinate Tub), meant to be run by a .tac file or manually. The
369         intermediate class has been removed. All .tac files are unchanged:
370         gatherers created by old versions of 'flogtool create-gatherer'
371         will continue to work.
372         (GathererService.do_rotate): return the name of the logfile that
373         was just closed and/or compressed, so tests can know where to
374         look.
375         * foolscap/test/test_logging.py (Gatherer): update to match
376         * foolscap/util.py (get_local_ip_for): update reactor comment
377
378 2008-07-30  Brian Warner  <warner@lothar.com>
379
380         * setup.py: update comment about bug #62 (pyopenssl problems)
381
382         * foolscap/test/test_logging.py (CLI.test_create_gatherer):
383         improve test coverage a little bit, by recording stdout
384         (CLI.test_create_incident_gatherer): exercise the 'flogtool
385         create-incident-gatherer' command
386         * foolscap/logging/cli.py (run_flogtool): capture stdout+stderr
387         (dispatch): same
388         * foolscap/logging/gatherer.py (create_log_gatherer): same
389         (create_incident_gatherer): same
390
391         * trees/tahoe/Makefile (figleaf-output): exclude foolscap/test/ from
392         the HTML results
393
394         * doc/logging.xhtml (Running an Incident Gatherer): describe the
395         Incident Gatherer, like the Log Gatherer but it only gathers
396         incidents. It also does classification, and will eventually do
397         reporting. No unit tests yet, but some manual system-level tests
398         have been run.
399         * foolscap/logging/gatherer.py (IncidentGatherer): implement it
400         * foolscap/logging/cli.py (Options.subCommands): add the CLI
401         command, named 'flogtool create-incident-gatherer'
402         * foolscap/logging/incident.py
403         (IncidentReporter.incident_declared): clean up incident naming
404         * foolscap/logging/interfaces.py (RILogPublisher.list_incidents): same
405         * foolscap/logging/log.py (FoolscapLogger.incident_recorded): same
406         * foolscap/logging/publish.py (LogPublisher.list_incident_names): same
407         * foolscap/test/test_logging.py
408         (IncidentPublisher.test_list_incident_names): test the
409         incident-naming cleanup
410
411 2008-07-29  Brian Warner  <warner@lothar.com>
412
413         * foolscap/logging/gatherer.py (GatheringBase): refactor the log
414         gatherer to share code with the upcoming incident gatherer
415         (LogGatherer.__init__): add a basedir= argument, rather than
416         using os.getcwd
417         * foolscap/test/test_logging.py (Gatherer): add basedir= argument
418
419         * doc/logging.xhtml (Setting up the logport): New feature (well,
420         it didn't work before, and now it does, so make it explicit): the
421         log-gatherer FURL can be configured (but will not be connected)
422         until after setLocation. This should resolve a crash I've seen in
423         Tahoe (which runs a slow /sbin/ifconfig command to figure out the
424         addresses to pass to setLocation) in which the app connects to the
425         log gatherer before it figures out its own location, and then gets
426         an exception during registerReference. Closes #55.
427         * foolscap/pb.py (Tub._maybeConnectToGatherer): don't initiate the
428         gatherer connection until locationHints is set
429         (Tub.setLocation): call _maybeConnectToGatherer after the location
430         is set. Also, don't let setLocation be called multiple times.
431         * foolscap/test/test_logging.py
432         (Publish.test_logport_furlfile2): test it
433         (Gatherer.test_log_gatherer2): same
434         (Gatherer.test_log_gatherer_furlfile2): same
435
436         * doc/logging.xhtml (Setting up the logport): slight API
437         restriction: the logport and its FURL are not available until
438         after Tub.setLocation is called. This results in a better error
439         message than the usual one inside registerReference.
440         * foolscap/pb.py (Tub.getLogPort): enforce the API restriction by
441         throwing an exception when it is violated
442         (Tub.getLogPortFURL): same
443         * foolscap/tokens.py (NoLocationError): new exception for it
444         * foolscap/test/test_tub.py (SetLocation.test_set_location): test it
445
446         * doc/logging.xhtml (Configuring a Log Gatherer): allow multiple
447         log-gatherer furls in the log-gatherer-furlfile
448         * foolscap/pb.py (Tub._maybeConnectToGatherer): same
449         * foolscap/logging/gatherer.py (LogGatherer.remote_logport):
450         return the subscribe_to_all Deferred, for testing
451         * foolscap/test/test_logging.py (Gatherer.test_log_gatherer):
452         refactor, to accomodate new test
453         (Gatherer.test_log_gatherer_furlfile_multiple): test it
454
455 2008-07-28  Brian Warner  <warner@lothar.com>
456
457         * foolscap/logging/interfaces.py (RILogPublisher.list_incidents):
458         change signature to remove tubid/incarnation from the response.
459         (RILogPublisher.subscribe_to_incidents): add pubsub interface for
460         incidents, including catch_up= and since=
461         (RILogObserver.new_incident): same
462         (RILogObserver.done_with_incident_catchup): same
463         * foolscap/logging/publish.py (IncidentSubscription): same
464         * foolscap/logging/incident.py
465         (IncidentReporter.finished_recording): tell the logger about the
466         incident name, so it can publish it.
467         * foolscap/logging/log.py
468         (FoolscapLogger.addImmediateIncidentObserver): same
469         (FoolscapLogger.incident_recorded): same
470         * foolscap/test/test_logging.py (IncidentPublisher._check_listed):
471         same
472         (IncidentPublisher.test_subscribe): test it
473
474         * foolscap/logging/interfaces.py (RISubscription.unsubscribe):
475         move the RILogPublisher.unsubscribe() method to the RISubscription
476         object, since that's a better place for it.
477         (RILogPublisher.unsubscribe): deprecate this one
478
479         * foolscap/logging/publish.py (Subscription.remote_unsubscribe): same
480
481         * foolscap/logging/publish.py (LogPublisher.remote_get_incident):
482         reject invalid incident names
483
484         * doc/logging.xhtml: add details about running a Log Gatherer
485         (Python 'logging' module): comment out this section, it is wrong
486
487 2008-07-09  Brian Warner  <warner@lothar.com>
488
489         * doc/specifications/logfiles.xhtml: fix typos
490         * doc/logging.xhtml (Remote log aggregation):  same
491
492 2008-07-07  Brian Warner  <warner@lothar.com>
493
494         * foolscap/logging/dumper.py (LogDumper): when dumping an Incident
495         Report, mark the triggering event with "[INCIDENT-TRIGGER]"
496
497         * foolscap/_version.py (verstr): bump revision to 0.2.9+ while
498         between releases
499         * misc/{dapper|edgy|feisty|gutsy|hardy|sarge|etch|sid}/debian/changelog:
500         same
501
502 2008-07-02  Brian Warner  <warner@lothar.com>
503
504         * foolscap/_version.py (verstr): release Foolscap-0.2.9
505         * misc/{dapper|edgy|feisty|gutsy|hardy|sarge|etch|sid}/debian/changelog:
506         same
507
508         * NEWS: update for the upcoming release
509         * MANIFEST.in: add gutsy/hardy directories
510
511 2008-07-02  Brian Warner  <warner@allmydata.com>
512
513         * foolscap/test/test_logging.py
514         (Publish.test_logpublisher_overload): change poller condition to
515         avoid spurious failures on slow systems
516
517         * misc/*/debian/watch: update to point at foolscap.lothar.com
518
519         * Makefile (debian-gutsy, debian-hardy): add .deb targets for
520         gutsy and hardy. The rules are the same as for feisty. Closes #76.
521         * misc/gutsy/*, misc/hardy/*: same
522
523         * foolscap/logging/publish.py (Subscription.send): change the
524         discard policy to discard-new instead of discard-random: in tests
525         with a busy Tahoe node, this seems to give good enough
526         behavior (probably since the busyness is bursty), although I can't
527         say we fully understand what's really going on. discard-new lets
528         us use a faster and simpler deque instead of requiring random
529         access to the list.
530         * foolscap/test/test_logging.py
531         (Publish.test_logpublisher_overload): update to match
532
533 2008-07-02  Brian Warner  <warner@lothar.com>
534
535         * foolscap/logging/publish.py (Subscription.send): add a
536         size-limited queue for sending messages to subscribers, with a
537         default queue size of 2000 entries. This should probably keep the
538         memory footprint bounded to perhaps 1MB. When the queue gets full,
539         we randomly discard old messages, so recent messages are more
540         likely to survive than earlier ones. We allow 10 messages to be
541         outstanding on the wire at once, to pipeline them a bit and
542         improve network utilization. Any errors during sending will cause
543         the subscription to be dropped. This should close #72.
544         * foolscap/logging/log.py (FoolscapLogger.addImmediateObserver):
545         add a new kind of observer, so that the logport publisher can also
546         avoid unboundedness in the eventual-send queue. If we can't throw
547         away messages fast enough, callers to log.msg will block, slowing
548         down the inlet rate.
549         * foolscap/test/test_logging.py
550         (Publish.test_logpublisher_overload): test it, by throwing 10k
551         messages at log.msg and counting how many make it through.
552
553         * foolscap/test/common.py (PollMixin): add a comment: this
554         chained-Deferred pattern will run up against python's recursion
555         limit if the check function is called more than about 300 times.
556
557 2008-07-01  Brian Warner  <warner@lothar.com>
558
559         * foolscap/logging/publish.py (Subscription): refactor a bit, in
560         preparation for #72 limit log-publishing queue size
561
562 2008-07-01  Brian Warner  <warner@allmydata.com>
563
564         * doc/logging.xhtml ("That Was Weird" Buttons): provide a simple
565         example of giving the user a way to trigger Incident logging.
566         Closes #75.
567
568         * foolscap/logging/interfaces.py (RILogPublisher.get_pid): new
569         interface, to retrieve the process ID through the logport
570         * foolscap/test/test_logging.py
571         (Publish.test_logpublisher_catchup._got_logport._check_pid): test it
572         * foolscap/logging/publish.py (LogPublisher.remote_get_pid):
573         implement it
574         * foolscap/logging/tail.py (LogTail._got_logpublisher._announce):
575         Use it, but tolerate old logports that don't offer it. Closes #71.
576
577         * foolscap/slicers/decimal_slicer.py: handle Decimal objects,
578         serializing them as a string. No constraints yet. Closes #50.
579         * foolscap/slicers/allslicers.py: import decimal_slicer
580         * foolscap/test/test_banana.py (ThereAndBackAgain.test_decimal):
581         test it
582
583         * foolscap/logging/tail.py (LogTail._got_logpublisher): exit if we
584         get an error while connecting or subscribing. Closes #63.
585         (LogTail._print_versions): print remote versions immediately after
586         connecting to the logport. Closes #70.
587
588         * foolscap/logging/log.py (FoolscapLogger.setLogDir): oops, allow
589         the incident directory to be re-used: os.makedirs throws an
590         exception if the directory already exists.
591         * foolscap/test/test_logging.py (Incidents.test_basic): test it
592
593
594         * foolscap/_version.py (verstr): bump revision to 0.2.8+ while
595         between releases
596         * misc/{dapper|edgy|etch|fesity|sarge|sid}/debian/changelog: same
597
598 2008-06-04  Brian Warner  <warner@lothar.com>
599
600         * foolscap/_version.py (verstr): release Foolscap-0.2.8
601         * misc/{dapper|edgy|etch|fesity|sarge|sid}/debian/changelog: same
602
603         * NEWS: update for the upcoming release
604
605 2008-06-04  Brian Warner  <warner@allmydata.com>
606
607         * foolscap/pb.py (Tub._tubsAreNotRestartable): fix args so that
608         these methods actually get run (and produce a useful error
609         message, instead of TypeError). Thanks to Brian Granger for the
610         patch. Closes #65.
611         * foolscap/test/test_tub.py (Shutdown.test_doublestop): test it
612         * foolscap/test/common.py (ShouldFailMixin.shouldFail): add some
613         support code
614
615         * foolscap/referenceable.py (RemoteReferenceOnly.getPeer): new
616         method to get the IP address and port number of the other end of a
617         connection. This returns a twisted.internet.interfaces.IAddress
618         provider. Loopback connections give
619         foolscap.broker.LoopbackAddress instances. Real remote connections
620         give twisted.internet.address.IPv4Address instances, so you can use
621         rref.getPeer().host and rref.getPeer().port on them. Closes #45.
622
623         * setup.py: add an "extras_require" clause to the
624         setuptools-specific setup args, to declare that our
625         "secure_connections" feature requires pyOpenSSL. This helps other
626         packages, which can declare a dependency on
627         "Foolscap[secure_connections]", rather than claiming to require
628         pyOpenSSL themselves. Addresses #66.
629
630         * foolscap/pb.py (Tub.registerReference): fix an exception that
631         occurs if you call this with both name= and furlFile= and the
632         furlFile already exists. Also prohibit attempts to change the name
633         to something other than what is in the furlFile. Thanks to Brian
634         Granger for the patch. Closes #64.
635
636         * foolscap/_version.py (verstr): bump revision to 0.2.7+ while
637         between releases
638         * misc/{dapper|edgy|etch|fesity|sarge|sid}/debian/changelog: same
639
640 2008-05-13  Brian Warner  <warner@lothar.com>
641
642         * foolscap/_version.py (verstr): release Foolscap-0.2.7
643         * misc/{dapper|edgy|etch|fesity|sarge|sid}/debian/changelog: same
644
645         * NEWS: update for new "OMG flogtool is broken" release.
646
647 2008-05-12  Brian Warner  <warner@allmydata.com>
648
649         * foolscap/logging/cli.py (run_flogtool): fix use of sys.argv,
650         the previous version was completely broken
651
652         * foolscap/_version.py (verstr): bump revision to 0.2.6+ while
653         between releases
654         * misc/{dapper|edgy|etch|fesity|sarge|sid}/debian/changelog: same
655
656 2008-05-06  Brian Warner  <warner@lothar.com>
657
658         * foolscap/_version.py (verstr): release Foolscap-0.2.6
659         * misc/{dapper|edgy|etch|fesity|sarge|sid}/debian/changelog: same
660
661         * NEWS: update for the upcoming release
662
663 2008-05-05  Brian Warner  <warner@allmydata.com>
664
665         * foolscap/test/test_logging.py (Web): add tests for 'flogtool
666         web-viewer'
667         * foolscap/logging/web.py (WebViewer.start): make this class more
668         amenable to being tested
669
670         * foolscap/logging/interfaces.py: misc cleanups
671         (RILogPublisher.list_incidents): provide an interface to retrieve
672         stored incident reports from a logport.
673         (RILogPublisher.get_incident): same
674         * foolscap/logging/publish.py (LogPublisher): same
675         * foolscap/test/test_logging.py (IncidentPublisher): test it
676         * foolscap/pb.py (Tub.setup): make the Tub's logger a bit easier
677         to override, for tests
678
679         * foolscap/logging/incident.py (IncidentReporter): make the
680         compressed logfile use a temporary name until we've closed it, so
681         later observers don't get tricked into using an incomplete
682         compressed logfile (they should use the more-complete uncompressed
683         logfile instead).
684         (IncidentReporter.incident_declared): make it easier to turn off
685         the gather-trailing-events behavior
686         (NonTrailingIncidentReporter): convenience subclass that does that
687
688         * doc/logging.xhtml: update to match current reality, remove some
689         TODO warnings
690
691         * foolscap/logging/log.py (FoolscapLogger): rename
692         setIncidentReporterClass to setIncidentReporterFactory
693         * foolscap/test/test_logging.py (Incidents.test_customize): same
694
695         * foolscap/logging/interfaces.py (RISubscription): remove spurious
696         'pass', figleaf thought it was real code
697
698         * bin/flogtool: split out the CLI dispatcher to..
699         * foolscap/logging/cli.py (run_flogtool): here, to help with #51
700         (run_flogtool): make it possible to run with a wrapper, closes #51.
701         * foolscap/test/test_logging.py (CLI.test_wrapper): test a wrapper,
702         provide an example of how to build one
703         * foolscap/logging/gatherer.py (CreateGatherOptions.optFlags): add
704         a --quiet flag to make the unit test less noisy
705
706         * misc/testutils/trial_figleaf.py: make this compatible with
707         twisted-8.0.x: the earlier version didn't write out any coverage
708         data on newer twisteds
709
710         * foolscap/logging/log.py (FoolscapLogger.setLogDir): wire up
711         Incident handling. We still need incident publishing. This gets
712         us most of the way to #61.
713         (setIncidentQualifier): this customizes the qualification function
714         (setIncidentReporterClass): this customizes the reporter/recorder
715         * foolscap/logging/levels.py: move log.WEIRD and friends here to
716         avoid circular import problems elsewhere. They are still available
717         from log.py .
718         * foolscap/logging/incident.py (IncidentReporter.incident_declared):
719         flush the uncompressed logfile just before we switch into
720         gather-trailing-events mode
721         (IncidentReporter.stop_recording): oops, fix typo
722         * foolscap/test/test_logging.py (Incidents): test most
723         incident-handling functionality
724
725
726 2008-05-02  Brian Warner  <warner@allmydata.com>
727
728         * foolscap/logging/incident.py: start to implement Incident
729         handling, for ticket #61. Not complete yet, might be completely
730         broken, needs tests and to be wired up.
731         * foolscap/logging/log.py (FoolscapLogger.setIncidentQualifier):
732         start to add the new interfaces, not complete yetxo
733         * foolscap/logging/interfaces.py (IIncidentReporter): same
734         * doc/logging.xhtml (Incidents): document the new features
735
736 2008-05-01  Brian Warner  <warner@allmydata.com>
737
738         * doc/logging.xhtml: fix discussion of format=, since the
739         instructions and examples were simply wrong
740
741         * doc/specifications/logfiles.xhtml (Logfile Headers): define
742         "headers", a separate dictionary at the start of the logfile that
743         contains metadata. The specific use for this will be the
744         "Triggering Event" that gets put into incident reports, once we
745         implement those. This induces a backwards compatibility break:
746         logfiles produced after this change will probably not be tolerated
747         by tools like 'flogtool dump' from before this point. The other
748         direction is ok: newer tools can handle either format.
749         * foolscap/logging/gatherer.py (LogGatherer._open_savefile): emit
750         a header, with type="gatherer", and a starting timestamp in
751         "start". Refactor a bit to make this easier.
752         * foolscap/logging/tail.py (LogPrinter): emit a header, with
753         type="tail"
754         * foolscap/logging/log.py (LogFileObserver): emit a header, with
755         type="log-file-observer", and a "threshold" key
756         * foolscap/logging/dumper.py (LogDumper.start): tolerate headers
757         * foolscap/logging/filter.py (Filter.run): same
758         * foolscap/logging/web.py (WebViewer.process_logfiles): same
759         * foolscap/test/test_logging.py: update tests to match
760
761         * doc/specifications/logfiles.xhtml: document the current saved
762         logfile format (event dictionaries, pickled wrapper dicts)
763
764         * foolscap/referenceable.py (SturdyRef): accept multiple
765         connection hints in unauthenticated FURLs. This fixes a test
766         failure induced by the #60 changes when pyOpenSSL is unavailable.
767         * doc/using-foolscap.xhtml: document the new feature.
768
769         * foolscap/referenceable.py (SturdyRef): tolerate extensions in
770         tubid and location-hints fields, change FURL parsing, store
771         structured hints in the SturdyRef instead of just strings. This
772         should give us some wiggle room in the future to gracefully
773         transition applications to using new features while retaining
774         backwards compatibilty. Many thanks to Zooko for the suggestion.
775         Closes #60.
776         * foolscap/negotiate.py (TubConnector): same
777         * foolscap/test/test_sturdyref.py (URL.testTubIDExtensions): new
778         tests for it
779         (URL.testLocationHintExtensions): same
780         * foolscap/test/test_tub.py (SetLocation.test_set_location):
781         update to match
782         * foolscap/test/test_gifts.py (Bad): same
783         * foolscap/test/test_negotiate.py
784         (Versus.testVersusHTTPServerAuthenticated): same
785         * foolscap/base32.py (is_base32): new utility function
786         * foolscap/test/test_util.py (Base32.test_is_base32): test it
787
788 2008-04-22  Brian Warner  <warner@lothar.com>
789
790         * doc/listings/command-client.py: don't emit extra newlines, use
791         /usr/bin/env on shbang line
792         * doc/listings/command-server.py: use /usr/bin/env on shbang line
793
794 2008-04-22  Brian Warner  <warner@allmydata.com>
795
796         * foolscap/logging/filter.py: add "--above UNUSUAL" option (to
797         discard events below the given level", and "--from [TUBID]" (to
798         discard events that weren't recorded by the given tubid).
799
800         * foolscap/logging/dumper.py (LogDumper.print_event): use
801         --rx-time to show both event-generation time and event-receive
802         time in the logs, useful if you suspect the application is getting
803         bogged down and events are being delivered slowly.
804         (LogDumper.print_event): Use a different format to display failure
805         tracebacks.
806
807         * foolscap/logging/web.py (WebViewer.get_events): catch
808         ValueError, mention it as a possible truncated pickle file
809
810         * foolscap/logging/log.py (FoolscapLogger.msg): if something goes
811         wrong, print both str() and repr() in case it helps figure out the
812         problem
813
814         * foolscap/logging/dumper.py (LogDumper.print_event): include
815         failure tracebacks in 'flogtool dump' output
816
817 2008-04-09  Brian Warner  <warner@allmydata.com>
818
819         * foolscap/constraint.py (Constraint.checkOpentype): always
820         accept ('reference',) sequences. The per-token constraint checking
821         system is a defense against resource-exhaustion attacks, and
822         shared reference don't consume any more memory or stack frames
823         than any other object. The check-all-args that CallUnslicer does
824         just before delivering the arguments is responsible for making
825         sure the final (resolved) types all match the constraint. By
826         allowing shared references here, we fix a bug in which a schema
827         violation was raised when python combined two equivalent tuples
828         into a single object.
829         * foolscap/test/test_call.py (TestCall.testMega3): test it
830         * foolscap/test/common.py (MegaSchema3): same
831
832         * setup.py: finally remove zip_safe=False
833
834         * foolscap/test/test_interfaces.py (TestInterface.testStack):
835         allow the test to pass even if the source code isn't
836         available (i.e. it's locked away inside an egg). This ought to
837         remove the need for zip_safe=False.
838
839         * foolscap/test/test_logging.py (Tail.test_logprinter): make the
840         test pass on python2.5: I think twisted now emits type(exception)
841         instead of str(exception), or something: the printed form changed.
842
843         * foolscap/schema.py (PolyConstraint): improve error messages
844
845         * foolscap/test/test_logging.py (Tail.test_logprinter): improve
846         error messages, to figure out why this fails on python2.5
847
848         * foolscap/__init__.py (_unused): add __version__, to hush pyflakes
849
850         * foolscap/test/test_logging.py (Publish.test_logpublisher): make
851         the test work with twisted-8.0.x, which puts more information in
852         log.err Failures than earlier versions did.
853
854         * foolscap/__init__.py (__version__): move version from here..
855         * foolscap/_version.py (verstr): .. to here
856         * foolscap/setup.py: merge zooko's patch to get foolscap version
857         by scanning foolscap/_version.py instead of importing foolscap.
858         This makes setuptools a lot happier: it doesn't need to have
859         Twisted installed (so foolscap can be imported) while it's
860         building foolscap as part of automatic dependency satisfaction.
861         Also change the shebang line to use /usr/bin/env, and import (but
862         do not use) setuptools if it is available. We set 'zip_safe=False'
863         in the extra setuptools arguments because two of the unit tests
864         assert that their stack traces have source code lines in them,
865         and that doesn't happen if foolscap is living inside an egg.
866         We will probably change those tests soon and allow zipped eggs.
867
868 2008-03-31  Brian Warner  <warner@allmydata.com>
869
870         * foolscap/test/test_logging.py (Tail): basic tests for
871         logging.tail
872         * foolscap/logging/tail.py (LogPrinter.remote_msg): parameterize
873         the output filehandle so we can test it
874
875         * foolscap/logging/gatherer.py (LogGatherer): remove the "Z"
876         suffix from the from- and to- timestamps that we put into
877         filenames, since we're actually using localtime. If and when we
878         switch to use UTC, we'll bring the Z back. Also remove the hyphens
879         between the time portions: from-2008-03-31-161721 instead of
880         from-2008-03-31-16-17-21. I'm still looking for a format that
881         feels readable, scannable, and clear.
882
883         * foolscap/logging/tail.py (LogPrinter.formatted_print): remove
884         spurious "0" from timestamps: i.e. print "08:09:12.345" instead of
885         "08:09:120.345"
886         * foolscap/logging/web.py (LogEvent.to_html): same
887
888         * foolscap/__init__.py: bump revision to 0.2.5+ while between releases
889         * misc/{dapper|edgy|etch|fesity|sarge|sid}/debian/changelog: same
890
891 2008-03-25  Brian Warner  <warner@lothar.com>
892
893         * foolscap/__init__.py: release Foolscap-0.2.5
894         * misc/{dapper|edgy|etch|fesity|sarge|sid}/debian/changelog: same
895
896 2008-03-25  Brian Warner  <warner@lothar.com>
897
898         * MANIFEST.in: add LICENSE
899
900         * NEWS: update for the upcoming release
901
902         * bin/flogtool (Options.synopsis): update with all commands.
903         There's still something broken with --help output, though.
904
905         * doc/listings/command-server.py:
906         * doc/listings/command-client.py: new sample programs, a
907         client/server pair which lets the client trigger a specific
908         command to be run on the server. Like xfer-server.py, but for
909         running commands instead of transferring files.
910
911         * foolscap/test/common.py (PollMixin): refactor a bit, to extract
912         the poll() method for use by other tests
913         * foolscap/test/test_logging.py (Publish.test_logpublisher):
914         improve the timing a bit, by waiting until the observer has heard
915         only silence for a full second, instead of starting the verify
916         pass one second after subscribing.
917         (Publish.test_logpublisher_catchup): same. It makes a bigger
918         difference here, because catch_up=True means that we'll be seeing
919         several hundred messages, which may take a non-trivial amount of
920         time to receive. I was seeing intermittent test failures with the
921         one-second-from-subscribe stall.
922
923 2008-03-24  Brian Warner  <warner@lothar.com>
924
925         * foolscap/logging/interfaces.py (RILogPublisher.subscribe_to_all):
926         add a catch_up= argument, which causes the publisher to dump all
927         its stored messages just after adding the subscriber. Closes #49.
928         * foolscap/logging/log.py (FoolscapLogger.get_buffered_events): same
929         (LogFileObserver.msg): catch+print exceptions while pickling events
930         * foolscap/logging/publish.py (LogPublisher): add catch_up=, make
931         sure that any log events arrive after subscribe_to_all() has
932         returned, to make event sequencing easier on the subscriber. Also
933         make sure that any catch-up events arrive before subsequent log
934         events.
935         * foolscap/logging/tail.py: add --catch-up option, make sure we
936         remain compatible with <=0.2.4 publishers (as long as you don't
937         use --catch-up)
938         * foolscap/test/test_logging.py (Publish.test_logpublisher_catchup):
939         test it
940         (Publish.test_logpublisher_catchup): make test more reliable
941
942         * LICENSE: make it clear that Foolscap ships under the MIT license,
943         the same as Twisted uses. Closes #47.
944         * README: same
945         * misc/{dapper|edgy|etch|fesity|sarge|sid}/debian/copyright: same
946
947 2008-03-24  Brian Warner  <warner@allmydata.com>
948
949         * foolscap/logging/dumper.py (LogDumper.print_event): event dicts
950         store the printable tubid, not a binary form
951         * foolscap/logging/gatherer.py (Observer.__init__): same
952         (LogGatherer.remote_logport): same
953         * foolscap/logging/interfaces.py (TubID): same
954         * foolscap/logging/web.py (LogEvent.__init__): same
955         * foolscap/logging/gatherer.py (LogGatherer.__init__): make bzip=
956         argument optional, for unit tests
957
958         * foolscap/logging/tail.py: fix --save-to, also put exception
959         information into the twistd.log when we can't pickle the event
960
961         * foolscap/logging/gatherer.py: add --rotate and --bzip options to
962         'flogtool create-gatherer': rotate the logfile every N seconds,
963         and optionally compress the results. Each logfile gets named like
964         from-2008-03-24-20-31-46Z--to-2008-03-24-20-31-56Z.flog.bz2 , and
965         the open one is named from-2008-03-24-20-32-16Z--to-present.flog .
966         Sending SIGHUP to the gatherer will force a rotation. Closes #48.
967
968         * foolscap/logging/tail.py: add --save-to option to 'flogtool
969         tail', which saves the log events to a file (in addition to
970         printing them to stdout). 'flogtool dump' can be used on the saved
971         file later. Also refactor things a bit to let us grab the
972         tubid from the target furl, since this gets recorded in the
973         save file format.
974         * foolscap/logging/gatherer.py (LogSaver): move to tail.py
975
976         * foolscap/logging/tail.py (LogPrinter): print formatted event
977         lines by default. Use the new --verbose option to dump raw event
978         dictionaries. Closes #43.
979         * bin/flogtool (dispatch): same
980
981 2008-02-17  Brian Warner  <warner@lothar.com>
982
983         * doc/using-foolscap.xhtml: fix href, thanks to Stephen Waterbury
984         for the catch. Note that the .xhtml points to .xhtml, and lore
985         converts the target of the link to .html in the .html output.
986         * doc/copyable.xhtml: same
987
988         * foolscap/logging/gatherer.py: make 'flogtool create-gatherer' to
989         build a .tac file (which can be launched with twistd) rather than
990         starting a gatherer right away. This is much more useable in
991         practice.
992         * bin/flogtool: same
993
994 2008-01-31  Brian Warner  <warner@allmydata.com>
995
996         * foolscap/test/test_tub.py: hush pyflakes, make it work without
997         crypto too
998
999         * doc/listings/xfer-server.py:
1000         * doc/listings/xfer-client.py: new sample programs, a
1001         client/server pair which allow the client to put files in the
1002         server's directory. Useful as a replacement for restricted-command
1003         passphraseless ssh key arrangements.
1004
1005         * foolscap/pb.py (Tub.setLocationAutomatically): new method that
1006         guesses an externally-visible IP address and uses it to call
1007         setLocation().
1008         * foolscap/test/test_tub.py (SetLocation.test_set_location): test