Adobe AIRでログを出力する方法

2011.08.19

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AIRでローカルにログを出力するサンプルです。 AIRのバージョンは2.6で試しています。

LineFormattedTargetを拡張してLogTargetクラスの作成します。 internalLogをオーバーライドしてログをアプリケーション記憶領域ディレクトリにファイル出力するようにしました。

package logging {
  
import flash.errors.IOError;
import flash.events.StatusEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.LocalConnection;

import mx.core.mx_internal;
import mx.formatters.DateFormatter;
import mx.logging.ILogger;
import mx.logging.Log;
import mx.logging.LogEvent;
import mx.logging.targets.LineFormattedTarget;

use namespace mx_internal;

public class MyTarget extends LineFormattedTarget {
  
  /** DateFormatter */
  private var formatter:DateFormatter;
  
  /**
   * コンストラクタ
   */
  public function MyTarget() {
    super();
    Log.addTarget(this);
    
    formatter = new DateFormatter();
    formatter.formatString = "YYYY-MM-DD";
  }
  
  /**
   * ログ書き込み処理
   */
  override mx_internal function internalLog(message:String):void {
    
    try {
      var fileName:String = formatter.format(new Date()) + ".txt";
      var file:File = File.applicationStorageDirectory.
        resolvePath("app-storage:/log/" + fileName);
      var stream:FileStream = new FileStream();
      stream.open(file, FileMode.APPEND);
      message += "\n";
      message = message.replace(/\n/g, File.lineEnding);
      stream.writeMultiByte(message, File.systemCharset);
      
    } catch(error:IOError) {
    } finally {
      stream.close();
    }
  }
}
}

以下は作成したMyTargetクラスのサンプルになります。 ボタンを押すとログが出力されます。ついでにグローバルエラー発生時にもログに出力されるようにしてみました。

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:logging="logging.*"
    applicationComplete="onApplicationComplete(event)">
    
  <fx:Declarations>
    <logging:MyTarget
      includeDate="true"
      includeTime="true"
      includeLevel="true"
      includeCategory="true"/>
  </fx:Declarations>
  
  <fx:Script>
    <![CDATA[
      import flash.utils.getQualifiedClassName;
      
      import mx.collections.ArrayCollection;
      import mx.events.FlexEvent;
      import mx.logging.ILogger;
      import mx.logging.Log;
      
      private var logger:ILogger;
      
      /**
       * 初期処理
       */
      protected function onApplicationComplete(event:FlexEvent):void{
        logger = Log.getLogger(getQualifiedClassName(this));
        
        loaderInfo.uncaughtErrorEvents.addEventListener(
          UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);
      }
      
      /**
       * グローバルエラーの処理
       */
      private function onUncaughtError(event:UncaughtErrorEvent):void {
        logger.fatal(event.toString());
        event.preventDefault();
      }
    ]]>
  </fx:Script>
  
  <s:Button label="click" click="logger.debug('Button Click')"/>
</s:WindowedApplication>