Skip to content
darwin edited this page Sep 13, 2010 · 36 revisions

FireLogger Protocol

Hey boy! so you want to implement FireLogger support for your language?

Overview

FireLogger content is sent from server to client via HTTP headers. To be safe it is BASE64 encoded UTF-8 JSON broken into multiple FireLogger headers.

Server can send multiple JSONs in one response, I call it packets. That is why each FireLogger header has hex id which should be assigned by server for every new packet (for example FirePython generates this as random ID).

These are main reasons:

  1. we don’t want to interfere with response content (it may be anything from HTML, javascript, CSS or unknown binary data)
  2. to keep it simple and safe (opening other communication channel with server would be from non-trivial to impossible – you know firewalls and such)
  3. JSON is easy for FireLogger addon (Javascript) and every server-side environment has libraries for serialization into JSON, so no big deal here

Request Headers

You have to take care about incoming request headers in your server side library:

  • X-FireLogger – presence of this header says that FireLogger is ready to receive your packets, value is FireLogger version
    • you must emit packets only if you encounter this header
    • you should warn user if there is version mismatch between your library and FireLogger
  • X-FireLoggerAuth – authentication token
    • you should check against this token if you have password to protect server-side

Authentication

The auth token is md5_hex(#FireLoggerPassword##), of course replace with actual password.

Reponse

You can render more packets into response, each with new id.

Packet structure is following:


{ errors: [...], // optional logs: [...] // optional }
  • errors – array of internal exceptions (maybe you don’t want to use this at all)
  • logs – array of actual log records

Example of packet with one log record is following:


{ "logs": [{ "args": { "py/tuple": ["/", { "action": "index", "controller": "welcome" }, { "multi": { "dicts": { "py/tuple": [{ "_items": "[('action', u'index'), ('controller', u'welcome')]", "_": "MultiDict([('action', u'index'), ('controller', u'welcome')])" }, { "reason": "'Not a POST request'", "_": "" }] }, "_": "NestedMultiDict([('action', u'index'), ('controller', u'welcome')])" }, "errors": "ignore", "decode_keys": true, "_": "UnicodeMultiDict([(u'action', u'index'), (u'controller', u'welcome')])", "encoding": "utf-8" }] }, "name": "www", "thread": -1610029280, "level": "debug", "process": 64884, "timestamp": 1237161193396626, "threadName": "MainThread", "pathname": "/opt/local/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/logging/__init__.py", "lineno": 1327, "template": "Dispatching %s to %s (%s)", "time": "23:53:13.396", "exc_text": null, "message": "Dispatching / to {'action': u'index', 'controller': u'welcome'} (UnicodeMultiDict([(u'action', u'index'), (u'controller', u'welcome')]))" }] }
Clone this wiki locally