Dart Cookbook
上QQ阅读APP看书,第一时间看更新

Adding logging to your app

Every production app needs a logger functionality that allows you to output log messages at varying levels of severity (information/warning/debug) to the (web browser's debug) console or a file. This recipe will enable you to do just that quickly and easily.

Getting ready

Use the logging package developed by the Dart team available from pub for this purpose. Add it to your pubspec.yaml file, and add the code line import 'package:logging/logging.dart'; to your code. See it in action in bank_terminal_polymer. We add the import to the code of the Polymer component and model class BankAccount.

How to do it...

  1. In web\bank_account.dart, we have at the top level the following code:
    import 'package:logging/logging.dart';
    final Logger log = new Logger('Bank Account'); 
    
  2. We change the constructor to the following code:
    BankAccount.created() : super.created() {
        setupLogger();
        log.info('Bank Account component is created');
      }
    setupLogger() is the place where you can define the format of your logs, the following code presents a minimal format:
    setupLogger() {
        // Set up logger.
     Logger.root.level = Level.ALL;
     Logger.root.onRecord.listen((LogRecord rec) {
    print('${rec.level.name}: ${rec.time}: ${rec.message}');
         });
      }
  3. In checkAmount(), we add the following warning message:
    checkAmount(String in_amount) {
        try {
          amount = double.parse(in_amount);
        } on FormatException catch(ex) {
     log.warning("Amount $in_amount is not a double!");
          return false;
        }
        return true;
      }
  4. In the model class in lib\bank_account.dart file, we add an "info" message when the BankAccount object is created: log.info('Bank Account is created'), and in the transact method, we add "severe message" when the balance becomes negative:
    transact(double amount) {
        balance += amount;
        if (amount < 0 && (-amount) > balance) {
     log.severe("Balance will go negative!");
        }
        date_modified = new DateTime.now();
    }
  5. If we then run the app, input an amount 50q, and then an amount -5000, which will make our balance negative. This means we will get the following console output:

    INFO: 2014-04-28 11:27:33.525: Bank Account component is created

    FINE: 2014-04-28 11:27:33.551: [Instance of '_Binding']: bindProperties: [value] to [bank-account].[Symbol("bac")]

    FINE: 2014-04-28 11:27:33.557: [bank-account] cancelUnbindAll

    FINE: 2014-04-28 11:27:33.561: [bank-app] cancelUnbindAll

    INFO: 2014-04-28 11:27:33.561: Bank Account is created

    FINE: 2014-04-28 11:27:39.172: >>> [bank-account]: dispatch enter

    INFO: 2014-04-28 11:27:39.176: <<< [bank-account]: dispatch enter

    WARNING: 2014-04-28 11:27:44.089: Amount 50qs is not a double!

    SEVERE: 2014-04-28 11:29:02.778: Balance will go negative!

    INFO: 2014-04-28 11:29:02.778: <<< [bank-account]: dispatch transact

How it works...

The object of the Logging class must first be configured; otherwise, nothing happens. This is done in setupLogger(), which does the following things:

  • It sets the level of the messages (choose between SHOUT, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL, or OFF, or predefine your own).
  • It sets up an event handler to listen for the onRecord stream. This processes objects of type LogRecord, which have access to the name, time, message, and stacktrace. Then, you code what you want to do with this event, print it to the console, write it in a file, send it in a mail, and so on.

There's more...

The following remarks tell you what to do in some special cases. To quickly display errors in a web app, you can add the following code in your code:

window.console.error('Something bad occurred');

If you want to log something asynchronously, use this snippet:

Future futr = doAsync();
futr.then((result) {
 log.fine('This result came back: $result');
  processResult(result);
})
.catchError((e, stackTrace) => log.severe('Something went wrong
 - ', e, stackTrace));