save non-string object on LogRecord (#28)

Save non-string object on `LogRecord` so that a handler can access the original object instead of just its
`toString()`
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 32204e7..953c763 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,14 @@
+## 0.11.3
+
+* Added optional `LogRecord.object` field.
+
+* `Logger.log` sets `LogRecord.object` if the message is not a string or a
+  function that returns a string. So that a handler can access the original
+  object instead of just its `toString()`.
+
 ## 0.11.2
 
-* Added Logger.detached - a convinience factory to obtain a logger that is not
+* Added Logger.detached - a convenience factory to obtain a logger that is not
   attached to this library's logger hierarchy.
 
 ## 0.11.1+1
diff --git a/lib/logging.dart b/lib/logging.dart
index 493d859..4866329 100644
--- a/lib/logging.dart
+++ b/lib/logging.dart
@@ -154,19 +154,24 @@
    *
    * If [message] is a [Function], it will be lazy evaluated. Additionally, if
    * [message] or its evaluated value is not a [String], then 'toString()' will
-   * be called on it and the result will be logged.
+   * be called on the object and the result will be logged. The log record will
+   * contain a field holding the original object.
    *
-   * The log record will contain a field for the zone in which this call was
-   * made.
+   * The log record will also contain a field for the zone in which this call
+   * was made.
    * This can be advantagous if a log listener wants to handle records of
    * different zones differently (e.g. group log records by http-request if each
    * http-request handler runs in it's own zone).
    */
   void log(Level logLevel, message,
       [Object error, StackTrace stackTrace, Zone zone]) {
+    Object object;
     if (isLoggable(logLevel)) {
       if (message is Function) message = message();
-      if (message is! String) message = message.toString();
+      if (message is! String) {
+        object = message;
+        message = message.toString();
+      }
       if (stackTrace == null && logLevel >= recordStackTraceAtLevel) {
         try {
           throw "autogenerated stack trace for $logLevel $message";
@@ -178,7 +183,8 @@
       if (zone == null) zone = Zone.current;
 
       var record =
-          new LogRecord(logLevel, message, fullName, error, stackTrace, zone);
+          new LogRecord(logLevel, message, fullName, error, stackTrace, zone,
+              object);
 
       if (hierarchicalLoggingEnabled) {
         var target = this;
@@ -335,6 +341,9 @@
   final Level level;
   final String message;
 
+  /** Non-string message passed to Logger. */
+  final Object object;
+
   /** Logger where this record is stored. */
   final String loggerName;
 
@@ -356,7 +365,7 @@
   final Zone zone;
 
   LogRecord(this.level, this.message, this.loggerName,
-      [this.error, this.stackTrace, this.zone])
+      [this.error, this.stackTrace, this.zone, this.object])
       : time = new DateTime.now(),
         sequenceNumber = LogRecord._nextNumber++;
 
diff --git a/pubspec.yaml b/pubspec.yaml
index 2bbbe94..91d2cc7 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: logging
-version: 0.11.2
+version: 0.11.3
 author: Dart Team <misc@dartlang.org>
 description: >
   Provides APIs for debugging and error logging. This library introduces
diff --git a/test/logging_test.dart b/test/logging_test.dart
index 2f5bf60..863650b 100644
--- a/test/logging_test.dart
+++ b/test/logging_test.dart
@@ -529,17 +529,28 @@
     test('message logging - calls toString', () {
       root.level = Level.INFO;
       var messages = [];
+      var objects = [];
+      var object = new Object();
       root.onRecord.listen((record) {
         messages.add('${record.level}: ${record.message}');
+        objects.add(record.object);
       });
 
       root.info(5);
       root.info(false);
       root.info([1, 2, 3]);
       root.info(() => 10);
+      root.info(object);
 
-      expect(messages,
-          equals(['INFO: 5', 'INFO: false', 'INFO: [1, 2, 3]', 'INFO: 10',]));
+      expect(messages, equals([
+        'INFO: 5',
+        'INFO: false',
+        'INFO: [1, 2, 3]',
+        'INFO: 10',
+        "INFO: Instance of 'Object'"
+      ]));
+
+      expect(objects, [5, false, [1, 2, 3], 10, object]);
     });
   });