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')]))"
  }]
}

Important log fields:

  • message – plain log message as it would be logged by your text logger
  • template – template version of message, arguments should be marked as %X, where FireLogger doesn’t care about X
  • args – array of arguments to be replaced in template. it is your hard work to provide FireLogger with detailed representation of arguments as structured data so user can drill it down in the Watches window. note: in current example, there is “py/tuple” structure wrapping actual array. This is specific to Python jsonpickle library, FireLogger can unwrap it, but you should send plain array in this case.
  • level – debug level, one of debug,info,warning,error,exception
  • timestamp – unix timestamp of log record (sorting)
  • time – user friendly time to be displayed with log record
  • name – logger name – see green bubbles on the right of each log record
  • pathname, lineno – log line location in source file
Clone this wiki locally